当表单再次显示时,单选按钮保存上次检查而不是所需的检查

SAM*_*Pro 5 delphi radio-button

我有一些TRadioButton在SForm2和呼叫Form2Form1使用此代码:

procedure TForm1.btnCallForm2Click(Sender:TObject);
begin
  Form2.RadioButton2.Checked:= true;
  Form2.ShowModal;
end;
Run Code Online (Sandbox Code Playgroud)

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

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

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

MaG*_*GiC 7

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

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

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

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

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

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

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

Form2.ActiveControl := nil;
Run Code Online (Sandbox Code Playgroud)

或根据文档:

Form2.ActiveControl := Form2.RadioButton2;
Run Code Online (Sandbox Code Playgroud)

或者您可以销毁并重新创建表单,如下所示:

从 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;
Run Code Online (Sandbox Code Playgroud)

  • @kobik - 我稍微修改了答案来解释该行为。@Magic - 我希望你不介意。 (3认同)
  • @Sertac,感谢您对此进行了一些说明。 (3认同)