gpt4 book ai didi

delphi - 按标题搜索标签

转载 作者:行者123 更新时间:2023-12-03 15:02:55 29 4
gpt4 key购买 nike

我试图弄清楚如何通过标签的标题搜索标签:

for I := ComponentCount - 1 downto 0 do
begin
if Components[i] is TLabel then
if Components[i].Caption = mnNumber then
begin
Components[i].Left := Left;
Components[i].Top := Top + 8;
end;
end;

我收到错误:未声明的标识符:“Caption”
我该如何解决这个问题?

最佳答案

迭代Components[]是错误的方法。这只会产生表单所拥有的组件。您将错过任何动态添加的、不属于表单的组件或属于框架的组件。

您应该使用Controls[]。然而,这只产生第一代 child 。如果有更深的父/子嵌套,那么您需要递归。那是更多的工作。我使用一些助手来使其变得简单。我已将它们包含在这个单元中:

unit ControlEnumerator;

interface

uses
System.SysUtils, System.Generics.Collections, Vcl.Controls;

type
TControls = class
private
type
TEnumerator<T: TControl> = record
FControls: TArray<T>;
FIndex: Integer;
procedure Initialise(WinControl: TWinControl; Predicate: TFunc<T, Boolean>);
class function Count(WinControl: TWinControl; Predicate: TFunc<T, Boolean>): Integer; static;
function GetCurrent: T;
function MoveNext: Boolean;
property Current: T read GetCurrent;
end;
TEnumeratorFactory<T: TControl> = record
FWinControl: TWinControl;
FPredicate: TFunc<T, Boolean>;
function Count: Integer;
function Controls: TArray<T>;
function GetEnumerator: TEnumerator<T>;
end;
public
class procedure WalkControls<T: TControl>(WinControl: TWinControl; Predicate: TFunc<T, Boolean>; Method: TProc<T>); static;
class function Enumerator<T: TControl>(WinControl: TWinControl; Predicate: TFunc<T, Boolean>=nil): TEnumeratorFactory<T>; static;
class function ChildCount<T: TControl>(WinControl: TWinControl; Predicate: TFunc<T, Boolean>=nil): Integer; static;
end;

implementation

{ TControls.TEnumerator<T> }

procedure TControls.TEnumerator<T>.Initialise(WinControl: TWinControl; Predicate: TFunc<T, Boolean>);
var
List: TList<T>;
Method: TProc<T>;
begin
List := TObjectList<T>.Create(False);
Try
Method :=
procedure(Control: T)
begin
List.Add(Control);
end;
WalkControls<T>(WinControl, Predicate, Method);
FControls := List.ToArray;
Finally
List.Free;
End;
FIndex := -1;
end;

class function TControls.TEnumerator<T>.Count(WinControl: TWinControl; Predicate: TFunc<T, Boolean>): Integer;
var
Count: Integer;
Method: TProc<T>;
begin
Method :=
procedure(Control: T)
begin
inc(Count);
end;
Count := 0;
WalkControls<T>(WinControl, Predicate, Method);
Result := Count;
end;

function TControls.TEnumerator<T>.GetCurrent: T;
begin
Result := FControls[FIndex];
end;

function TControls.TEnumerator<T>.MoveNext: Boolean;
begin
inc(FIndex);
Result := FIndex<Length(FControls);
end;

{ TControls.TEnumeratorFactory<T> }

function TControls.TEnumeratorFactory<T>.Count: Integer;
begin
Result := TEnumerator<T>.Count(FWinControl, FPredicate);
end;

function TControls.TEnumeratorFactory<T>.Controls: TArray<T>;
var
Enumerator: TEnumerator<T>;
begin
Enumerator.Initialise(FWinControl, FPredicate);
Result := Enumerator.FControls;
end;

function TControls.TEnumeratorFactory<T>.GetEnumerator: TEnumerator<T>;
begin
Result.Initialise(FWinControl, FPredicate);
end;

class procedure TControls.WalkControls<T>(WinControl: TWinControl; Predicate: TFunc<T, Boolean>; Method: TProc<T>);
var
i: Integer;
Control: TControl;
Include: Boolean;
begin
if not Assigned(WinControl) then begin
exit;
end;
for i := 0 to WinControl.ControlCount-1 do begin
Control := WinControl.Controls[i];
if not (Control is T) then begin
Include := False;
end else if Assigned(Predicate) and not Predicate(Control) then begin
Include := False;
end else begin
Include := True;
end;
if Include then begin
Method(Control);
end;
if Control is TWinControl then begin
WalkControls(TWinControl(Control), Predicate, Method);
end;
end;
end;

class function TControls.Enumerator<T>(WinControl: TWinControl; Predicate: TFunc<T, Boolean>): TEnumeratorFactory<T>;
begin
Result.FWinControl := WinControl;
Result.FPredicate := Predicate;
end;

class function TControls.ChildCount<T>(WinControl: TWinControl; Predicate: TFunc<T, Boolean>): Integer;
begin
Result := Enumerator<T>(WinControl, Predicate).Count;
end;

end.

现在你可以这样解决你的问题:

var
lbl: TLabel;
....
for lbl in TControls.Enumerator<TLabel>(Form) do
if lbl.caption=mnNumber then
begin
lbl.Left := Left;
lbl.Top := Top + 8;
end;

或者您可以使用谓词将标题测试放入迭代器中:

var
Predicate: TControlPredicate;
lbl: TLabel;
....
Predicate := function(lbl: TLabel): Boolean
begin
Result := lbl.Caption='hello';
end;
for lbl in TControls.Enumerator<TLabel>(Form, Predicate) do
begin
lbl.Left := Left;
lbl.Top := Top + 8;
end;

关于delphi - 按标题搜索标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14892793/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com