Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 9 of 9 total
Thread Capture the caption value of runtime label
Sun, Mar 26 2017 7:55 PMPermanent Link

kamran

Hi

1. I create panels at runtime then use the panelonclick to capture the event to see what panel was clicked..
2. Additionally on the *same* created panel I create a label for each panel and assign it a value.

The CurrentPanelCaption gives a value  as required.
The CurrentLabelCaption .. I am not sure how I would access this.
eg. How can i capture the caption value of the label on the same PanelOnClick procedure as below.?

My Code:

procedure TMainFrm.PanelOnClick(Sender: TObject);
var CurrentID:Integer;
   CurrentPanelCaption:string;
   CurrentLabelCaption:string;
begin
 CurrentID := TPanel(Sender).Tag;
 CurrentPanelCaption := TPanel(Sender).CaptionBar.Caption;  
 CurrentLabelCaption := TPanel(Sender).TLabel.Caption;  <---------------
end;

Thanks

Kamran
Sun, Mar 26 2017 11:31 PMPermanent Link

Raul

Globestar Systems

Team Elevate Team Elevate

On 3/26/2017 7:55 PM, kamran wrote:
> 1. I create panels at runtime then use the panelonclick to capture the event to see what panel was clicked..
> 2. Additionally on the *same* created panel I create a label for each panel and assign it a value.

How are you creating this label and more specifically how are you naming
them (if at all) ?


> The CurrentPanelCaption gives a value  as required.
> The CurrentLabelCaption .. I am not sure how I would access this.
> eg. How can i capture the caption value of the label on the same PanelOnClick procedure as below.?

Few options that come to mind :

1. Loop thru the controls property of the panel and look for tlabel -
tricky part comes in when you have more than 1 tlabel so you should have
some way to identify this label vs some other label (either add
prefix/suffix to the name name or some data to other property like tag).

i'm not in front of EWB so this might not compile but something similar
to this :
....
for i:= 0 to TPanel(Sender).CountrolCount-1 do
begin
  if TPanel(Sender).Controls[i].Classname='TLabel' then
  begin
   CurrentLabelCaption  := TLabel(TPanel(Sender).Controls[i]).Caption;
   break;
  end;
end;
....


2. You could derive your own tpanel class and add the tlabel as class
property (and you'd to assign reference when you create it) so it's even
easier to access.


Raul



Mon, Mar 27 2017 3:56 AMPermanent Link

kamran

Hi Raul

I have the following procedure i use to create panels and with labels on it:

procedure TDataFrm.CreatePanels;
var i: integer;
  NewPanel:TPanel;
  NewLabel:TLabel;
begin
  MainFrm.BeginUpdate;
  try
     { Free old panels }
     for i := MainFrm.TablePlanPanel.ControlCount-1 downto 0 do
        if MainFrm.TablePlanPanel.Controls[i] is TPanel then
           MainFrm.TablePlanPanel.Controls[i].free;
     { Create  new panels }
     for i := 1 to Asset.RowCount do
     begin
        NewPanel := TPanel.create(MainFrm.TablePlanPanel);
        NewLabel := TLabel.create(NewPanel);  <------------------  label created here on the runtime panel
        With NewLabel do
        begin
          NewLabel.caption:=Asset.Columns['asset_status_description'].AsString;
          NewLabel.left:=20;
          NewLabel.Top:=30;
          NewLabel.Font.Color:=clYellow;
        end;
        with NewPanel do
        begin
           Tag := i * 20;
           CaptionBar.Height:=30;            
           CaptionBar.Caption :=Asset.Columns['asset_code'].AsString;
           CaptionBar.Font.Size:=12;
           CaptionBar.AllowMinimize:=False;
           CaptionBar.AllowClose:=False;
           CaptionBar.AllowMove:=False;
           OnClick := MainFrm.TablePanelOnClick;
           NewPanel.Width :=136;
           NewPanel.Height:=90;
           with Layout do
           begin
              Position := lpTopLeft;
              Consumption := lcBottom;
              OverFlow := loRight;
           end;
           with Margins do
           begin
              Left := 7;
              Top := 7;
           end;
        end;
        Asset.Next;
     end;

  finally
     MainFrm.EndUpdate;
  end;
end;

Thanks

Kamran

Raul wrote:
How are you creating this label and more specifically how are you naming
them (if at all) ?
Mon, Mar 27 2017 4:33 AMPermanent Link

Matthew Jones

Raul wrote:

> or some data to other property like tag).

Using Tag is indeed by far the best way. In my applications I often have a bunch of panels, and I use Tag to store the index of the object in a TObjectList that is being displayed, and is to be manipulated. When I create the panel at run time, all items on it are set to the same tag for speed of location.

--

Matthew Jones
Mon, Mar 27 2017 4:39 AMPermanent Link

Uli Becker

As Raul recommended: you have to assign a tag or a name to the label to
be able to identify it later.

In your case there might be another effective way:

> with NewPanel do
>          begin
>             Tag := i * 20;
>             CaptionBar.Height:=30;
>             CaptionBar.Caption :=Asset.Columns['asset_code'].AsString;

Tag := i * 20;

That's from a sample app I sent you. It doesn't do anything. Replace it by

Tag := Asset.Columns['id'].AsInteger;

provided that your table has an ID field with this name.

By doing so you can always identify the correct record in your dataset,
e.g.:

CurrentID := TPanel(Sender).Tag;
Asset.InitFind;
Asset.Columns['id'].AsInteger := CurrentID;
if Asset.Find(false,true) then   
   CurrentLabelCaption :=
Asset.Columns['asset_status_description'].AsString;

Uli


Mon, Mar 27 2017 10:10 AMPermanent Link

Raul

Globestar Systems

Team Elevate Team Elevate

On 3/27/2017 3:56 AM, kamran wrote:

Kamran

> I have the following procedure i use to create panels and with labels on it:

You got some good feedback from Uli and Matthew on using the Tag.

Using a custom panel class might work nicely as well since you're
creating it always in code so i'll list a really simple example using
the option 2 i had previously suggested :

Unit type section define a new custom panel type that stores reference
to your label :

type
   TPanelWithLblRef = class(TPanel)
     public
       lblRef:TLabel;
   end;

.....

and then in your code use TPanelWithLblRef instead of TPanel

so your function to create would be something like this

procedure TDataFrm.CreatePanels;
var i: integer;
   NewPanel:TPanelWithLblRef; <--- TPanelWithLblRef
   NewLabel:TLabel;
....
 for i := 1 to Asset.RowCount do
 begin
   NewPanel := TPanelWithLblRef.create(MainFrm.TablePlanPanel);
   NewLabel := TLabel.create(NewPanel);
   NewPanel.lblRef:= NewLabel;<-- store tlabel reference
....

and then in your code when you need to reference the label caption just
do this :

....
  CurrentPanelCaption := TPanel(Sender).CaptionBar.Caption;
  CurrentLabelCaption := TPanelWithLblRef(Sender).lblRef.Caption;
....


You could easily extend the TPanelWithLblRef even further so it
automatically manages the label (creates it and sets properties) but
example above should allow to see if it solves your problem.

Raul
Mon, Mar 27 2017 11:05 AMPermanent Link

Uli Becker

Raul,

> type
>    TPanelWithLblRef = class(TPanel)
>      public
>        lblRef:TLabel;
>    end;

That's an elegant solution with a minimum of code.

Uli
Mon, Mar 27 2017 3:03 PMPermanent Link

kamran

Hi,

Raul, Uli and Matthew

Thanks a lot for the pointers and sample code.
I think both the"tag" solution and "redefining the panel type" solutions are great.

Cheers

Kamran


Uli Becker wrote:

Raul,

> type
>    TPanelWithLblRef = class(TPanel)
>      public
>        lblRef:TLabel;
>    end;

That's an elegant solution with a minimum of code.

Uli
Tue, Mar 28 2017 3:50 AMPermanent Link

Matthew Jones

Raul wrote:

> if TPanel(Sender).Controls[i].Classname='TLabel' then

I just want to pick up on this, and suggest that it should be

if TPanel(Sender).Controls[i] is TLabel then

Unless there is a specific reason to really be a TLabel rather than a derived class etc.

I know it was an off the cuff example, but worth being clear of the capabilities for other's. Kamran has already adopted this anyway I see.

--

Matthew Jones
Image