使用ApplicationSettings存储WinForms RadioButtons的Checked属性

Cod*_*nis 5 .net vb.net radio-button winforms

我有一个包含3个单选按钮的WinForms对话框.我ApplicationSettings用来绑定每个RadioButton控件的Checked属性,但它没有做我期望它做的事情.现在我必须先点击每个单选按钮两次才能检查它并且所选的单选按钮没有被保留.

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

如何消除2倍点击单选按钮的需要?

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

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

sys*_*ich 6

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

如何消除2倍点击单选按钮的需要?

您可以将以下事件处理程序添加到GroupBox中三个RadioButton(其中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
Run Code Online (Sandbox Code Playgroud)

它可以正常工作,即使单击它后检查一个未检查的RadioButton需要半秒钟.

两年前(2008年)在Turbulent Intelect博客上存在的WinForms Databinding帖子的第5部分解释了这个问题的原因(谢谢你,ohadsc,链接):

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

我知道如果你可以将你的一组单选按钮绑定到枚举属性会有多棒.我真的这样做.你认为你只是想把一些Format和Parse事件连接起来转回你的枚举,一切都会好的.如果真的有效的话会很方便.但WinForms并没有因此而被削减.现在有3个完整版本(或者它是3.5版本吗?),情况就是如此.这是因为事件顺序,这不是MS可以切换而不会导致成千上万的开发人员真正被关闭的事情.

问题实际上归结为这样一个事实:与其他控件的数据属性不同,单选按钮的Checked属性实际上不会改变,直到焦点离开单选按钮.和所有WinForms控件一样,焦点实际上并没有留下单选按钮,直到将焦点放到另一个控件之后,实际上直到新焦点控件的Click事件触发后才开始.与单选按钮相关的结果是,如果您尝试绑定它们,数据源中的绑定属性实际上会落后您的单选按钮的可视状态一次单击.如果您只有两个单选按钮,则数据源将与可见状态完全相反,直到您单击其他不触发引用这些数据源属性的操作的位置.这可以使这成为一个真正令人愤怒的错误追踪.我几乎以为我是幻觉.

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


小智 6

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

这是我的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;
        }

    }
Run Code Online (Sandbox Code Playgroud)


Mat*_*ton 3

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

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

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

Properties.Settings.Default.Save();
Run Code Online (Sandbox Code Playgroud)

...保存设置。

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