【发布时间】:2015-09-15 15:15:06
【问题描述】:
我写了一个类似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 吗?
【问题讨论】:
标签: delphi custom-controls deserialization