触发弹出菜单项的标题属性。

3

我有一个弹出菜单,其中有一个名为 "Ativar" 的项目,但我不明白为什么这段代码不起作用:

procedure TForm6.Ativar1Click(Sender: TObject);
begin
  if ativar1.Caption='Ativar' then
  begin
    showmessage('Initialize procedure');
    ativar1.Caption:='Desativar';
  end else
  if ativar1.Caption='Desativar' then
  begin
    showmessage('Initialize procedure');
    ativar1.Caption:='Ativar';
  end;
end;

我认为编写代码时应该对对象的标题属性进行验证,如果它等于"启用",则激活并显示消息,并将标题属性更改为"禁用",而当标题属性等于"禁用"时,则显示消息并再次将属性更改为"启用"。那么问题出在哪里呢?


1
在UI组件的标题中不应该保留状态。如果它被翻译了怎么办?或者如果您改变主意并在对象检查器中使标题更长怎么办?那么您的逻辑将失败。 - Jeroen Wiert Pluimers
4个回答

2
使用“菜单中的StripHotKey”来替换加速键。
begin
  if StripHotKey(TMenuItem(Sender).Caption) = 'Ativar' then
  begin
    ShowMessage('Initialize procedure');
    TMenuItem(Sender).Caption := 'Desativar';
  end
  else if StripHotKey(TMenuItem(Sender).Caption) = 'Desativar' then
  begin
    ShowMessage('Initialize procedure');
    TMenuItem(Sender).Caption := 'Ativar';
  end;
end;

2

在 UI 组件的标题中不应该保留状态。如果它被翻译了怎么办?或者如果您改变主意并在对象检查器中使标题更长怎么办?那么您的逻辑将失败。

最好这样做:

  • 将状态从Caption移至单独的表单字段(我更喜欢使用枚举类型而不是布尔类型,所以状态字段是FAtivarState,类型是TAtivarState
  • 为了确保您能够翻译您的应用程序,将初始的AtivarCaption从对象检查器移动到resourcestring中,并为desactivar状态设置一个。 (请注意,我保留了两个状态的A键盘快捷键)
    如果您不需要进行翻译,则可以将resourcestring替换为const
  • 将标题分配和业务逻辑分开成两个方法(SetAtivarCaptionHandleAtivarChange
  • FormCreate事件方法(将其绑定到TForm6OnCreate事件)和Ativar1Click事件方法调用这些方法

像上面这样的结构化方法看起来需要额外付出很多努力,但实际上并不是这样的:它能够为您节省大量解决问题的时间,就像您在问题中遇到的那样。

示例代码:

// unit name, interface clause, uses list, etc ...

type
  TAtivarState = (asAtivar, asDesativar);
  TForm6 = class(TForm);
    procedure Ativar1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    FAtivarState: TAtivarState;
    procedure SetAtivarCaption(); virtual; 
    procedure HandleAtivarChange(); virtual; 

// implementation clause, uses list, etc ...

resourcestring
  AtivarCaption = '&Ativar';
  DestivarCaption = 'Des&ativar';

procedure TForm6.Ativar1Click(Sender: TObject);
begin
  HandleAtivarChange();
end;

procedure TForm6.FormCreate(Sender: TObject);
begin
  SetActivar1Caption();
end;

procedure TForm6.SetAtivarCaption();
begin
  if FAtivarState = asAtivar then
    Ativar1.Caption := AtivarCaption
  else
    Ativar1.Caption := DesativarCaption;
end;

procedure TForm6.HandleAtivarChange();
begin
  if FAtivarState = asAtivar then
  begin
    ShowMessage('Initialize procedure');
    FAtivarState := asDesativar;
  end
  else
  begin
    ShowMessage('Initialize procedure');
    FAtivarState := asAtivar;
  end;
  SetActivar1Caption();
end;

1
感谢您详细的解释,我会深入研究这个问题。 - V.Salles

1
那是因为如果你显示消息标题,你会看到'Ativar'字符串的代替符号'&Ativar',因此你的两个测试都失败了。你可以将'&'添加到你的测试中,但我强烈建议你使用其他属性,如标签或已选属性,具体取决于你在做什么。

0

我测试了你的代码,这个是完美运行的。只需要在你的条件检查中添加一个'&':

procedure TForm6.Ativar1Click(Sender: TObject);
begin
if ativar1.Caption='&Ativar' then
begin
  showmessage('Initialize procedure');
  ativar1.Caption:='Desativar';
end else
if ativar1.Caption='&Desativar' then
begin
  showmessage('Initialize procedure');
  ativar1.Caption:='Ativar';
end;

end;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接