【问题标题】:RadioButtons save last checked instead of desired one when form displayed again再次显示表单时,RadioButtons 保存上次检查而不是所需的
【发布时间】:2019-12-04 13:47:59
【问题描述】:

我在Form2 上有一些TRadioButtons,并使用此代码从Form1 调用Form2

procedure TForm1.btnCallForm2Click(Sender:TObject);
begin
  Form2.RadioButton2.Checked:= true;
  Form2.ShowModal;
end;

如果用户点击btnCallForm2,将显示Form2,然后用户点击RadioButton3并关闭表单,然后再次点击btnCallForm2重新打开它。

现在Form2 再次显示,但RadioButton3 被选中而不是RadioButton2

问:这是什么行为,是错误吗?如何设置检查我想要的RadioButton而不是用户在上一轮选择的内容?

【问题讨论】:

  • 这不是错误。您只是将 Caption 与当前的 Caption 和控件名称连接起来。只写Caption := (Sender as TComponent).Name;
  • Caption 是指表单标题,与Form1.CaptionSelf.Caption 相同。当您写 Caption:= Caption 时,这意味着 prev Form.Caption + (Sender as TComponent).Name。所以@TLama 已经说过使用Caption := (Sender as TComponent).Name; 而不是Caption:= Caption + (Sender as TComponent).Name;
  • @TLama,问题不在于标题(尽管它在 btnCallForm2Click 中的 ShowModal 之前已被清除)。我不想被选中的是 RadioButton。
  • @Sami,带有 Caption 我只想告诉你 RadioButton 被选中了两次。

标签: delphi radio-button


【解决方案1】:

这不是错误。你有这种“奇怪”行为的原因是如果 Form2 没有被销毁,那么下次它变得可见时(例如ShowModal)它会记住哪个控件具有焦点。

在您的情况下,最后一个焦点控件是 RadioButton3(因为您单击它以更改“选中”状态)。因此,即使您将“已选中”状态更改回 RadioButton2,下次激活表单时,焦点也会恢复到 RadioButton3。要恢复焦点,向控件发送WM_SETFOCUS。阅读documentation 的其余部分,了解按钮控件的默认消息处理:

WM_SETFOCUS   在获得焦点的按钮上绘制一个焦点矩形。 对于单选按钮和自动单选按钮,父窗口是 发送了BN_CLICKED 通知代码。

BN_CLICK 通知(WM_COMMAND 消息)将单选按钮的状态设置为选中。

可以在使用键盘导航单选按钮时找到此行为背后的基本原理。当您在其中一个单选按钮上按向上/向下箭头时,将选中下一个接收焦点的单选按钮。

此行为仅适用于单选按钮,例如,尝试对另一个控件(例如复选框)进行相同操作,当它具有焦点时其状态不会改变。您会看到一切都按预期进行

正如 kobik 所建议的,一个快速简单的解决方案是在显示 Form2 之前将 ActiveControl 设置为 nil

Form2.ActiveControl := nil;

或根据文档:

Form2.ActiveControl := Form2.RadioButton2;

或者你可以破坏并重新创建表单,如下所示:

从Project->Options->Forms中的AutoCreated Forms中移除Form2,并在ButtonClick事件中手动创建

procedure TForm1.btnCallForm2Click(Sender:TObject)
begin
  Form2 := TForm2.Create(nil);
  try
    Form2.RadioButton2.Checked:= true;
    Form2.ShowModal;
  finally
    FreeAndNil(Form2);
  end;
end;

【讨论】:

  • 我个人会采用同样的方法。但是为什么需要呢?为什么OP描述的行为?这是 IMO 真正的问题。
  • @kobik,回答已更新以涵盖对所描述行为的解释。
  • 好的,你让我相信集中控制在这里起作用。我仍然认为这是一个糟糕的设计,而且这种行为是出乎意料的,至少对我来说是这样。无论如何,另一种解决方案是在显示之前设置Form2.ActiveControl := nil
  • @kobik - 我稍微修改了答案以解释行为。 @Magic - 希望你不要介意。
  • @Sertac,感谢您对此有所了解。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-11
  • 1970-01-01
  • 2014-05-16
  • 1970-01-01
相关资源
最近更新 更多