如何将结果编码为组合框中的选择?
How to code a result to a selection from a combobox?
我在 Delphi 10.3 中有一个 TComboBox。我有一个包含 30 多个项目的组合框。我需要为组合框的每个项目编写不同的操作。目前我正在使用 if-else 语句。由于有 30 个不同的项目,if 语句会太长。有没有更快的方法来做到这一点?
这个完全取决于你的情况。在不知道您的确切情况的情况下几乎不可能回答您的问题。
不过,这里有一些想法。也许他们与你的情况有关,也许他们不是。
索引的简单参数化
在最好的情况下,您的 30 个动作可以被参数化。例如,假设组合框的项目是
Show 1
Show 10
Show 100
Show 1000
...
这将显示一个带有给定数字的消息框。在这种情况下,您不需要 30 个不同的过程(这里每个过程都由对 ShowMessage
的简单调用表示):
procedure TForm1.btnNextClick(Sender: TObject);
begin
case ComboBox1.ItemIndex of
0:
ShowMessage('1');
1:
ShowMessage('10');
2:
ShowMessage('100');
3:
ShowMessage('1000');
// ...
end;
end;
相反,您应该只使用一个过程,但带有一个参数:
procedure TForm1.btnNextClick(Sender: TObject);
begin
if ComboBox1.ItemIndex <> -1 then
ShowMessage(IntPower(10, ComboBox1.ItemIndex).ToString)
end;
关联对象的参数化
如果不能单独通过项目的索引来描述操作,您可以使用与每个项目关联的对象指针。也许用它来存储一个整数就足够了:
procedure TForm1.FormCreate(Sender: TObject);
begin
ComboBox1.Items.BeginUpdate;
try
ComboBox1.Items.Clear;
ComboBox1.Items.AddObject('Show 51', TObject(51));
ComboBox1.Items.AddObject('Show 111', TObject(111));
ComboBox1.Items.AddObject('Show 856', TObject(856));
ComboBox1.Items.AddObject('Show 1000', TObject(1000));
finally
ComboBox1.Items.EndUpdate;
end;
end;
procedure TForm1.btnNextClick(Sender: TObject);
begin
if ComboBox1.ItemIndex <> -1 then
ShowMessage(Integer(ComboBox1.Items.Objects[ComboBox1.ItemIndex]).ToString);
end;
否则,您可以让它成为指向具有任意数量数据(整数、字符串...)的某个对象的真正指针。
无关程序
上面的例子都要求过程可以参数化,即用一个带参数的过程代替。如果不是这种情况,如果程序完全不相关,则您需要采用不同的方法。但同样,哪种方法最合适取决于您的具体情况。
这里有几个例子。
简单的案例陈述
在设计时,将项目设置为 Play sound
、Run Notepad
和 Show Start Menu
。
procedure PlaySound;
begin
MessageBeep(MB_ICONINFORMATION);
end;
procedure RunNotepad;
begin
ShellExecute(Form1.Handle, nil, 'notepad', nil, nil, SW_SHOWNORMAL)
end;
procedure ShowStartMenu;
begin
Form1.Perform(WM_SYSCOMMAND, SC_TASKLIST, 0)
end;
procedure TForm1.btnNextClick(Sender: TObject);
begin
case ComboBox1.ItemIndex of
0:
PlaySound;
1:
RunNotepad;
2:
ShowStartMenu;
end;
end;
将程序指针与项目一起存储
procedure PlaySound;
begin
MessageBeep(MB_ICONINFORMATION);
end;
procedure RunNotepad;
begin
ShellExecute(Form1.Handle, nil, 'notepad', nil, nil, SW_SHOWNORMAL)
end;
procedure ShowStartMenu;
begin
Form1.Perform(WM_SYSCOMMAND, SC_TASKLIST, 0)
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
ComboBox1.Items.BeginUpdate;
try
ComboBox1.Items.Clear;
ComboBox1.Items.AddObject('Play sound', TObject(@PlaySound));
ComboBox1.Items.AddObject('Run notepad', TObject(@RunNotepad));
ComboBox1.Items.AddObject('ShowStartMenu', TObject(@ShowStartMenu));
finally
ComboBox1.Items.EndUpdate;
end;
end;
procedure TForm1.btnNextClick(Sender: TObject);
begin
if ComboBox1.ItemIndex <> -1 then
TProcedure(ComboBox1.Items.Objects[ComboBox1.ItemIndex])();
end;
好处:没有混淆索引的风险;操作“附加”到项目。
使用命令字典
也许您的应用程序有一组全局命令,用英文单词表示。然后您可能想使用字典来获取与某个词关联的过程。这也可以用于组合框。在设计时,假设有三个项目:beep
、write
和 start
:
type
TForm1 = class(TForm)
ComboBox1: TComboBox;
btnNext: TButton;
procedure btnNextClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
FCommands: TDictionary<string, TProcedure>;
public
end;
procedure PlaySound;
begin
MessageBeep(MB_ICONINFORMATION);
end;
procedure RunNotepad;
begin
ShellExecute(Form1.Handle, nil, 'notepad', nil, nil, SW_SHOWNORMAL)
end;
procedure ShowStartMenu;
begin
Form1.Perform(WM_SYSCOMMAND, SC_TASKLIST, 0)
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
FCommands := TDictionary<string, TProcedure>.Create;
FCommands.Add('beep', PlaySound);
FCommands.Add('write', RunNotepad);
FCommands.Add('start', ShowStartMenu);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
FCommands.Free;
end;
procedure TForm1.btnNextClick(Sender: TObject);
var
Cmd: TProcedure;
begin
if
(ComboBox1.ItemIndex <> -1)
and
FCommands.TryGetValue(ComboBox1.Items[ComboBox1.ItemIndex], Cmd)
then
Cmd();
end;
我在 Delphi 10.3 中有一个 TComboBox。我有一个包含 30 多个项目的组合框。我需要为组合框的每个项目编写不同的操作。目前我正在使用 if-else 语句。由于有 30 个不同的项目,if 语句会太长。有没有更快的方法来做到这一点?
这个完全取决于你的情况。在不知道您的确切情况的情况下几乎不可能回答您的问题。
不过,这里有一些想法。也许他们与你的情况有关,也许他们不是。
索引的简单参数化
在最好的情况下,您的 30 个动作可以被参数化。例如,假设组合框的项目是
Show 1
Show 10
Show 100
Show 1000
...
这将显示一个带有给定数字的消息框。在这种情况下,您不需要 30 个不同的过程(这里每个过程都由对 ShowMessage
的简单调用表示):
procedure TForm1.btnNextClick(Sender: TObject);
begin
case ComboBox1.ItemIndex of
0:
ShowMessage('1');
1:
ShowMessage('10');
2:
ShowMessage('100');
3:
ShowMessage('1000');
// ...
end;
end;
相反,您应该只使用一个过程,但带有一个参数:
procedure TForm1.btnNextClick(Sender: TObject);
begin
if ComboBox1.ItemIndex <> -1 then
ShowMessage(IntPower(10, ComboBox1.ItemIndex).ToString)
end;
关联对象的参数化
如果不能单独通过项目的索引来描述操作,您可以使用与每个项目关联的对象指针。也许用它来存储一个整数就足够了:
procedure TForm1.FormCreate(Sender: TObject);
begin
ComboBox1.Items.BeginUpdate;
try
ComboBox1.Items.Clear;
ComboBox1.Items.AddObject('Show 51', TObject(51));
ComboBox1.Items.AddObject('Show 111', TObject(111));
ComboBox1.Items.AddObject('Show 856', TObject(856));
ComboBox1.Items.AddObject('Show 1000', TObject(1000));
finally
ComboBox1.Items.EndUpdate;
end;
end;
procedure TForm1.btnNextClick(Sender: TObject);
begin
if ComboBox1.ItemIndex <> -1 then
ShowMessage(Integer(ComboBox1.Items.Objects[ComboBox1.ItemIndex]).ToString);
end;
否则,您可以让它成为指向具有任意数量数据(整数、字符串...)的某个对象的真正指针。
无关程序
上面的例子都要求过程可以参数化,即用一个带参数的过程代替。如果不是这种情况,如果程序完全不相关,则您需要采用不同的方法。但同样,哪种方法最合适取决于您的具体情况。
这里有几个例子。
简单的案例陈述
在设计时,将项目设置为 Play sound
、Run Notepad
和 Show Start Menu
。
procedure PlaySound;
begin
MessageBeep(MB_ICONINFORMATION);
end;
procedure RunNotepad;
begin
ShellExecute(Form1.Handle, nil, 'notepad', nil, nil, SW_SHOWNORMAL)
end;
procedure ShowStartMenu;
begin
Form1.Perform(WM_SYSCOMMAND, SC_TASKLIST, 0)
end;
procedure TForm1.btnNextClick(Sender: TObject);
begin
case ComboBox1.ItemIndex of
0:
PlaySound;
1:
RunNotepad;
2:
ShowStartMenu;
end;
end;
将程序指针与项目一起存储
procedure PlaySound;
begin
MessageBeep(MB_ICONINFORMATION);
end;
procedure RunNotepad;
begin
ShellExecute(Form1.Handle, nil, 'notepad', nil, nil, SW_SHOWNORMAL)
end;
procedure ShowStartMenu;
begin
Form1.Perform(WM_SYSCOMMAND, SC_TASKLIST, 0)
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
ComboBox1.Items.BeginUpdate;
try
ComboBox1.Items.Clear;
ComboBox1.Items.AddObject('Play sound', TObject(@PlaySound));
ComboBox1.Items.AddObject('Run notepad', TObject(@RunNotepad));
ComboBox1.Items.AddObject('ShowStartMenu', TObject(@ShowStartMenu));
finally
ComboBox1.Items.EndUpdate;
end;
end;
procedure TForm1.btnNextClick(Sender: TObject);
begin
if ComboBox1.ItemIndex <> -1 then
TProcedure(ComboBox1.Items.Objects[ComboBox1.ItemIndex])();
end;
好处:没有混淆索引的风险;操作“附加”到项目。
使用命令字典
也许您的应用程序有一组全局命令,用英文单词表示。然后您可能想使用字典来获取与某个词关联的过程。这也可以用于组合框。在设计时,假设有三个项目:beep
、write
和 start
:
type
TForm1 = class(TForm)
ComboBox1: TComboBox;
btnNext: TButton;
procedure btnNextClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
FCommands: TDictionary<string, TProcedure>;
public
end;
procedure PlaySound;
begin
MessageBeep(MB_ICONINFORMATION);
end;
procedure RunNotepad;
begin
ShellExecute(Form1.Handle, nil, 'notepad', nil, nil, SW_SHOWNORMAL)
end;
procedure ShowStartMenu;
begin
Form1.Perform(WM_SYSCOMMAND, SC_TASKLIST, 0)
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
FCommands := TDictionary<string, TProcedure>.Create;
FCommands.Add('beep', PlaySound);
FCommands.Add('write', RunNotepad);
FCommands.Add('start', ShowStartMenu);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
FCommands.Free;
end;
procedure TForm1.btnNextClick(Sender: TObject);
var
Cmd: TProcedure;
begin
if
(ComboBox1.ItemIndex <> -1)
and
FCommands.TryGetValue(ComboBox1.Items[ComboBox1.ItemIndex], Cmd)
then
Cmd();
end;