Reputation: 469
Today I have a question that is simple to ask, but not so simple to answer: is there a way to get a component by its tag?
I have a group of frames and in each of them the component I would like to focus is tagged as "1". The tagged component may be a TEdit, TMemo, TListBox, and so on.
From a frame controller, I would like to focus the control tagged as "1" in each frame according to the frame itself. Can I accomplish this task without knowing the component type or name?
Upvotes: 0
Views: 1954
Reputation: 595827
Loop through the frame's Components[]
list. Tag
is a public property of TComponent
.
var
Comp: TComponent;
I: Integer;
begin
for i := 0 to frame.ComponentCount-1 do
begin
Comp := frame.Components[i];
if Comp.Tag = 1 then
begin
(Comp as TWinControl).SetFocus;
break;
end;
end;
end;
An alternative would be to define an interface
that each frame implements, and have it simply return/manipulate the desired component directly without having to hunt for it:
type
ITaggedComponent = interface
['{e5cfb88e-8c5d-4898-a008-742dd8d86698}']
function GetTaggedComponent: TComponent;
procedure FocusTaggedComponent;
property TaggedComponent: TComponent read GetTaggedComponent;
end;
type
TFrame1 = class(TFrame, ITaggedComponent)
Edit1: TEdit;
...
public
function GetTaggedComponent: TComponent;
procedure FocusTaggedComponent;
end;
TFrame2 = class(TFrame, ITaggedComponent)
Memo1: TMemo;
...
public
function GetTaggedComponent: TComponent;
procedure FocusTaggedComponent;
end;
TFrame3 = class(TFrame, ITaggedComponent)
ListBox1: TListBox;
...
public
function GetTaggedComponent: TComponent;
procedure FocusTaggedComponent;
end;
...
function TFrame1.GetTaggedComponent: TComponent;
begin
Result := Edit1;
end;
procedure TFrame1.FocusTaggedComponent;
begin
Edit1.SetFocus;
end;
function TFrame2.GetTaggedComponent: TComponent;
begin
Result := Memo1;
end;
procedure TFrame2.FocusTaggedComponent;
begin
Memo1.SetFocus;
end;
function TFrame3.GetTaggedComponent: TComponent;
begin
Result := ListBox1;
end;
procedure TFrame3.FocusTaggedComponent;
begin
ListBox1.SetFocus;
end;
...
Then you can do this:
var
Intf: ITaggedComponent;
begin
if Supports(frame, ITaggedComponent, Intf) then
Intf.FocusTaggedComponent;
end;
Upvotes: 2
Reputation: 6013
This should get your component - you can do what you want with it (set focus etc.) afterwards - assuming it is not nil
function TFrameController.GetMainControlForFrame( const pFrame : TFrame ) : TComponent;
begin
for Result in pFrame do
begin
if Result.Tag = 1 then
begin
exit;
end;
end;
// else
Result := nil;
end;
I deliberately did not set the focus internally because you might want to get the same component for some other purpose.
Upvotes: 0