我写了一个TListBox
- 类似控件(类似于Doctor Bob's SpeedBox)。
运行正常,但有一个问题:分配给属性Items
的字符串在启动时未加载到TListBox
字段中。我发现,我的程序SetItem
未在创建时被调用,因为组件阅读器会为字符串分配TStrings.Add
。
该控件的源代码:
unit HKS.Controls.FilterListBox;
interface
uses
System.Classes, Vcl.Controls, Vcl.StdCtrls;
type
THKSFilterListBox = class(TWinControl)
strict private
FEdit: TEdit;
FItems: TStrings;
FListBox: TListBox;
procedure SetItems(const Value: TStrings);
procedure ReInitListBoxItems;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
published
property Items: TStrings read FItems write SetItems;
end;
procedure Register;
implementation
uses
System.SysUtils, Vcl.Graphics, Winapi.Windows;
procedure Register;
begin
RegisterComponents('HKS', [THKSFilterListBox]);
end;
{ THKSFilterListBox }
constructor THKSFilterListBox.Create(AOwner: TComponent);
begin
inherited;
FItems := TStringList.Create;
FEdit := TEdit.Create(Self);
FEdit.Parent := Self;
FListBox := TListBox.Create(Self);
FListBox.Parent := Self;
ReInitListBoxItems; // has no effect since data is not loaded yet
end;
destructor THKSFilterListBox.Destroy;
begin
FreeAndNil(FListBox);
FreeAndNil(FEdit);
FreeAndNil(FItems);
inherited;
end;
procedure THKSFilterListBox.ReInitListBoxItems;
var
LFilterText: String;
begin
LFilterText := AnsiUpperCase(Trim(FEdit.Text));
FListBox.Items.BeginUpdate;
try
if LFilterText <> '' then
begin
// some filter routine
end else
FListBox.Items.Assign(FItems);
finally
FListBox.Items.EndUpdate;
end;
end;
procedure THKSFilterListBox.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
const
cEditHeightAddon = 12;
cMargin = 2;
var
LListBoxTop: Integer;
begin
inherited;
FEdit.SetBounds(0, 0, Self.Width, Abs(Font.Height) + cEditHeightAddon);
LListBoxTop := FEdit.BoundsRect.Bottom + cMargin;
FListBox.SetBounds(0, LListBoxTop, Self.Width, Self.Height - LListBoxTop);
end;
// is not called on startup because items are added one by one with "TStrings.Add"
procedure THKSFilterListBox.SetItems(const Value: TStrings);
begin
FItems.Assign(Value);
ReInitListBoxItems;
end;
end.
我需要我自己的Items
实例,因为不会显示所有项目,具体取决于FEdit.Text
中的过滤字符串。
在从dfm加载属性后,有没有办法调用ReInitListBoxItems
?
答案 0 :(得分:2)
在从dfm加载属性后,有没有办法调用ReInitListBoxItems?
覆盖组件的Loaded
方法。
在读取表单文件后初始化组件 存储器中。
不要调用受保护的Loaded方法。流媒体系统调用 从流加载组件的表单后,此方法。
当流媒体系统从表单加载表单或数据模块时 它首先通过调用它来构造表单组件 然后,构造函数从表单文件中读取其属性值。后 读取所有组件的所有属性值,即流 系统按顺序调用每个组件的Loaded方法 组件已创建。这为组件提供了机会 初始化任何依赖于其他组件或的值的数据 本身的其他部分。
type
THKSFilterListBox = class(TWinControl)
...
protected
procedure Loaded; override;
...
end;
procedure THKSFilterListBox.Loaded;
begin
inherited;
ReInitListBoxItems;
end;