5

我有一个包含 3 个单选按钮的 WinForms 对话框。我正在使用ApplicationSettings绑定每个RadioButton控件的 Checked 属性,但它没有做我期望它做的事情。现在,我必须在每个单选按钮被选中之前单击它两次,并且选定的单选按钮不会被保留。

关闭表单时是否需要执行一行代码来保存用户设置?

如何消除两次单击单选按钮的需要?

有没有更好的方法来保留这种类型的用户设置?我确实在对话框类上有一个公共属性,它根据选中的单选按钮获取/设置枚举值,但我没有看到将该属性绑定到用户设置的简单方法。

编辑:应该指定我正在使用 vb.net。我认为这意味着My.Settings而不是Properties.Settings.

4

4 回答 4

6

我回答你问题的这一部分:

如何消除两次单击单选按钮的需要?

您可以将以下事件处理程序添加到 GroupBox 中三个 RadioButtons(其中 Checked 属性绑定到应用程序设置)中的每一个的 Click 事件中:

Private Sub RadioButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tomRadioButton.Click, dickRadioButton.Click, harryRadioButton.Click
    If sender.Checked = False Then
        sender.Checked = True
    End If
End Sub

它可以工作,即使在单击后检查未选中的 RadioButton 需要半秒钟。

问题的原因在两年前(2008 年)Turbulent Intelect 博客上的Surviving WinForms Databinding帖子的第 5 节中进行了解释(感谢ohadsc提供链接):

规则 5:不要绑定到可点击的单选按钮

我知道如果您可以将一堆单选按钮绑定到一个枚举属性,那该有多好。我真的。你认为你只是要连接一些 Format 和 Parse 事件来翻译回你的枚举,一切都会好起来的。如果它真的有效,那就太方便了。但是 WinForms 并不适合这个。对于现在的 3 个完整版本(或者是 3.5 个版本?),情况就是如此。这是因为事件顺序,这不是 MS 可以在不让成千上万的开发人员真正感到厌烦的情况下切换的东西。

问题实际上归结为这样一个事实,即与其他控件的数据属性不同,单选按钮的 Checked 属性在焦点离开单选按钮之前实际上并没有改变。与所有 WinForms 控件一样,焦点实际上不会离开单选按钮,直到焦点被赋予另一个控件之后,实际上直到新焦点控件的 Click 事件被触发之后。与单选按钮有关的结果是,如果您尝试绑定到它们,数据源中的绑定属性实际上会一键滞后于单选按钮的视觉状态. 如果您只有两个单选按钮,则数据源将与可见状态完全相反,直到您单击不会触发引用这些数据源属性的操作的其他位置。这可以使它成为一个非常令人恼火的错误。我差点以为自己出现幻觉了。

现在,老实说,有可能让它发挥作用。但它是有史以来最笨拙的笨拙。好吧,也许它不是那么糟糕......但它肯定是一个混乱的黑客。真正应该已经可用的东西需要做很多工作。据我所知,在不放弃数据绑定机制的情况下解决此问题的唯一方法是从本质上制作您自己的 RadioButton 控件,并具有实际有用的属性更改和事件顺序。您可以从头开始编写一个,或者子类 RadioButton 并使用自定义消息处理覆盖所有事件逻辑。

于 2010-06-26T12:00:27.650 回答
6

感谢 Geoffrey Van Wyk 和 ohadsc(链接),我想出了以下自定义控件。它基本上是一个自定义框架,它将在其中包含的所有单选按钮上自动实现 Geoffrey 的代码。优点是您现在可以使用 ApplicationSettings 来绑定控件的选中属性,并且它将按预期工作。

这是我制作自定义控件的 c# 代码:

 public partial class RadioPanel : System.Windows.Forms.Panel
    {
        protected override void OnControlAdded(ControlEventArgs e)
        {
            base.OnControlAdded(e);
            var radioButton = e.Control as RadioButton;
            if (radioButton != null)
                radioButton.Click += radioButton_Click;
        }

        void radioButton_Click(object sender, EventArgs e)
        {
            var radio = (RadioButton)sender;
            if (!radio.Checked)
                radio.Checked = true;
        }

    }
于 2011-08-02T14:32:58.810 回答
3

我可以回答你问题的这一部分:

关闭表单时是否需要执行一行代码来保存用户设置?

应用程序设置存储在您的Settings类中,在Properties命名空间中。该类Settings有一个名为 的静态属性Default,它表示您的应用程序的当前设置。因此,在主窗体的 Closing 事件中,您调用:

Properties.Settings.Default.Save();

...保存设置。

同样,您可以使用设置的名称以编程方式访问设置:(Properties.Settings.Default.MyRadioButtonState或您所称的任何名称)。

于 2009-06-01T23:25:38.483 回答
3

此行为在此处的第 5 项中进行了解释:

http://turbulentintellect.blogspot.com/2008/07/surviving-winforms-databinding.html

一个可能的解决方案是自定义 GroupGox: Best way to databind a group of a radiobuttons in WinForms

于 2010-03-06T17:42:50.400 回答