I just thought of how I can improve (refactor?) some of my panels. In one of my projects I have 200+ panels to organize layout (on various PageControls) and about 20 of them are used to split view for side by side view - so I set in the ParentPanel OnResize: Panel.Width := ParentPanel.Width div 2; (and Panel has Align = alLeft and the other Panel has Align = alClient so they split the ParentPanel view)


I just thought of how I can improve (refactor?) some of my panels. In one of my projects I have 200+ panels to organize layout (on various PageControls) and about 20 of them are used to split view for side by side view - so I set in the ParentPanel OnResize: Panel.Width := ParentPanel.Width div 2; (and Panel has Align = alLeft and the other Panel has Align = alClient so they split the ParentPanel view)
Simple, it works OK.

The problem is that each of this panels need to have this Width code in their Parent OnResize and I set this in Object Inspector. And is annoying to track down which panel has this set and which doesn't. So I wanted to simplify this by extending the TPanel:

TPanel = class(Vcl.ExtCtrls.TPanel)
private
FSetChildPanelWidthAsHalf: boolean; // Enable Width div 2
FChildPanel: TPanel; // Set which Panel get set Width div 2
protected
procedure Resize; override;
public
property SetChildPanelWidthAsHalf: Boolean read FSetChildPanelWidthAsHalf write FSetChildPanelWidthAsHalf;
property SetChildPanel: TPanel read FChildPanel write FChildPanel;
end;

procedure TPanel.Resize;
begin
if FSetChildPanelWidthAsHalf then
if FChildPanel <> nil then
FChildPanel.Width := Width div 2;
inherited;
end;


And I set these new properties on FormCreate:

Panel1.SetChildPanel := Panel2;
Panel1.SetChildPanelWidthAsHalf := True;

As tested this works great!

The panels are organized on PageControl Tabs, so at one time I only see a few of them (which tab is active), not all 200+ panels are visible at the same.

Since I've never done anything like this and not sure how testing can really be done (except if it works), I'm worried how this will work when going live, so I have a few questions:

1. The most obvious: Am I missing something really obvious and I don't see it that will be a problem once it goes live? Is there a better way of doing this?

2. inherited - is it better to put it after or before my custom code? I put it after, since I assume the Width is so basic property that it should be executed first and after that any code set in each Panel OnResize.

3. Can this 'slow down' the whole user interface since the new Resize gets triggered on all 200+ panel? Even though only for 20 the code will be executed, but right now the rest of 180 has nothing set in OnResize.

Thank you for any comments on this!

I'm attaching a picture of what I'm talking about: Panel1 is Parent Panel of Panel2 and Panel3. Panel2.Align = alLeft and Panel3.Align - alClient. OnResize of ParentPanel a Panel2.Width := ParentPanel.Width div 2;

Comments

  1. Uwe Raabe Yes, especially in another project I have up to 4 panels, and I organize them side by side, 2x Up and 1x down, or 3x Up and 1x down... with up to 3 splitters. Here the grid panel would help a lot, but again I need splitters.

    ReplyDelete
  2. Mike Torrettinni - That is a matter of preference, I guess. We have our own control wrappers which are easy to manage and which allows us to chose where the displayed data are coming from (db, memory, json, file, etc), while retaining the same functionality in all grids - but they are not populated up in design mode. In fact, they are mostly not really configured design time at all - but set up in code. Frames and form .dfm file changes are not fun to merge in a VCS.

    Another challenge with frames is visual inheritance. It is very easy to nudge something out of place, after it has been dropped somewhere.

    I have a "frame test bench" where I work with each individual frame (or frame of frames) for development and testing - instead of working with the whole application all the time.

    ReplyDelete

Post a Comment