根据触发事件的组合框更新相应的标签
Update corresponding label depending on which combobox fired the event
我有一个包含 n
ComboBoxes
和 n
Labels
的程序,我想根据相邻的选择更新相应的 Label
ComboBox
即 ComboBox2
将更新 Label2
。
我为每个 ComboBox
使用相同的事件处理程序,目前正在检查 Combobox1
或 Combobox2
是否触发了事件处理程序。有没有办法把ComboBox
的ItemIndex
传给程序,比如Sender.ItemIndex
?这目前不是一个选项,并给出错误 'TObject' does not contain a member named 'ItemIndex'
.
procedure TForm2.ComboBoxChange(Sender: TObject);
begin
if Sender = ComboBox1 then
Label1.Caption := ComboBox1.Items.Strings[ComboBox1.ItemIndex]
else
Label2.Caption := ComboBox2.Items.Strings[ComboBox2.ItemIndex];
end;
此代码具有所需的行为,但显然无法扩展。
选项 1
这是最稳健的。
让你的表单拥有私有成员
private
FControlPairs: TArray<TPair<TComboBox, TLabel>>;
procedure InitControlPairs;
并在创建表单时调用 InitControlPairs
(在其构造函数中或在其 OnCreate
处理程序中):
procedure TForm1.InitControlPairs;
begin
FControlPairs :=
[
TPair<TComboBox, TLabel>.Create(ComboBox1, Label1),
TPair<TComboBox, TLabel>.Create(ComboBox2, Label2),
TPair<TComboBox, TLabel>.Create(ComboBox3, Label3)
]
end;
您需要手动将控件添加到此数组。这是这种方法的缺点。但你只需要做一次,就在这里。然后其他一切都可以自动完成。
现在,这就是它变得非常棒的地方:让您所有的组合框共享这个 OnChange
处理程序:
procedure TForm1.ComboBoxChanged(Sender: TObject);
var
i: Integer;
begin
for i := 0 to High(FControlPairs) do
if FControlPairs[i].Key = Sender then
FControlPairs[i].Value.Caption := FControlPairs[i].Key.Text;
end;
选项 2
忘记任何私有字段。现在改为确保每一对都有唯一的 Tag
。所以第一个组合框和标签都有 Tag = 1
,第二对有 Tag = 2
,依此类推。那么你可以简单地做
procedure TForm1.ComboBoxChanged(Sender: TObject);
var
TargetTag: Integer;
CB: TComboBox;
i: Integer;
begin
if Sender is TComboBox then
begin
CB := TComboBox(Sender);
TargetTag := CB.Tag;
for i := 0 to ControlCount - 1 do
if (Controls[i].Tag = TargetTag) and (Controls[i] is TLabel) then
begin
TLabel(Controls[i]).Caption := CB.Text;
Break;
end;
end;
end;
作为共享组合框事件处理程序。这里的缺点是您必须确保控制窗体上所有控件的 Tag 属性(至少与标签具有相同的父级)。此外,它们必须具有相同的父控件。
每个组件都有一个 Tag
属性 继承自 TComponent
,其中 Tag
是一个指针大小的整数。因此,您可以将每个 TLabel
指针直接存储在相应的 TComboBox.Tag
中,例如:
procedure TForm2.FormCreate(Sender: TObject);
begin
ComboBox1.Tag := NativeInt(Label1);
ComboBox2.Tag := NativeInt(Label2);
end;
这样,ComboBoxChange()
就可以直接访问修改后的TComboBox
的TLabel
了,eg:
procedure TForm2.ComboBoxChange(Sender: TObject);
var
CB: TComboBox;
begin
CB := TComboBox(Sender);
if CB.Tag <> 0 then
TLabel(CB.Tag).Caption := CB.Items.Strings[CB.ItemIndex];
end;
我有一个包含 n
ComboBoxes
和 n
Labels
的程序,我想根据相邻的选择更新相应的 Label
ComboBox
即 ComboBox2
将更新 Label2
。
我为每个 ComboBox
使用相同的事件处理程序,目前正在检查 Combobox1
或 Combobox2
是否触发了事件处理程序。有没有办法把ComboBox
的ItemIndex
传给程序,比如Sender.ItemIndex
?这目前不是一个选项,并给出错误 'TObject' does not contain a member named 'ItemIndex'
.
procedure TForm2.ComboBoxChange(Sender: TObject);
begin
if Sender = ComboBox1 then
Label1.Caption := ComboBox1.Items.Strings[ComboBox1.ItemIndex]
else
Label2.Caption := ComboBox2.Items.Strings[ComboBox2.ItemIndex];
end;
此代码具有所需的行为,但显然无法扩展。
选项 1
这是最稳健的。
让你的表单拥有私有成员
private
FControlPairs: TArray<TPair<TComboBox, TLabel>>;
procedure InitControlPairs;
并在创建表单时调用 InitControlPairs
(在其构造函数中或在其 OnCreate
处理程序中):
procedure TForm1.InitControlPairs;
begin
FControlPairs :=
[
TPair<TComboBox, TLabel>.Create(ComboBox1, Label1),
TPair<TComboBox, TLabel>.Create(ComboBox2, Label2),
TPair<TComboBox, TLabel>.Create(ComboBox3, Label3)
]
end;
您需要手动将控件添加到此数组。这是这种方法的缺点。但你只需要做一次,就在这里。然后其他一切都可以自动完成。
现在,这就是它变得非常棒的地方:让您所有的组合框共享这个 OnChange
处理程序:
procedure TForm1.ComboBoxChanged(Sender: TObject);
var
i: Integer;
begin
for i := 0 to High(FControlPairs) do
if FControlPairs[i].Key = Sender then
FControlPairs[i].Value.Caption := FControlPairs[i].Key.Text;
end;
选项 2
忘记任何私有字段。现在改为确保每一对都有唯一的 Tag
。所以第一个组合框和标签都有 Tag = 1
,第二对有 Tag = 2
,依此类推。那么你可以简单地做
procedure TForm1.ComboBoxChanged(Sender: TObject);
var
TargetTag: Integer;
CB: TComboBox;
i: Integer;
begin
if Sender is TComboBox then
begin
CB := TComboBox(Sender);
TargetTag := CB.Tag;
for i := 0 to ControlCount - 1 do
if (Controls[i].Tag = TargetTag) and (Controls[i] is TLabel) then
begin
TLabel(Controls[i]).Caption := CB.Text;
Break;
end;
end;
end;
作为共享组合框事件处理程序。这里的缺点是您必须确保控制窗体上所有控件的 Tag 属性(至少与标签具有相同的父级)。此外,它们必须具有相同的父控件。
每个组件都有一个 Tag
属性 继承自 TComponent
,其中 Tag
是一个指针大小的整数。因此,您可以将每个 TLabel
指针直接存储在相应的 TComboBox.Tag
中,例如:
procedure TForm2.FormCreate(Sender: TObject);
begin
ComboBox1.Tag := NativeInt(Label1);
ComboBox2.Tag := NativeInt(Label2);
end;
这样,ComboBoxChange()
就可以直接访问修改后的TComboBox
的TLabel
了,eg:
procedure TForm2.ComboBoxChange(Sender: TObject);
var
CB: TComboBox;
begin
CB := TComboBox(Sender);
if CB.Tag <> 0 then
TLabel(CB.Tag).Caption := CB.Items.Strings[CB.ItemIndex];
end;