使用ApplicationSettings存储WinForms RadioButtons的Checked属性

5
我有一个 WinForms 对话框,其中包含 3 个单选按钮。我正在使用 ApplicationSettings 来绑定每个 RadioButton 控件的 Checked 属性,但它并没有达到我的预期效果。现在我必须要点击两次每个单选按钮才可以被选中,并且所选的单选按钮没有被持久化。
在窗体关闭时是否有一行代码需要执行来保存用户设置?
如何消除对单选按钮进行两次点击的需求?
是否有更好的方式来保留此类型的用户设置?我在对话框类上有一个公共属性,根据哪个单选按钮被选中获取/设置枚举值,但我没有看到将该属性绑定到用户设置的简单方法。 编辑:应该指定我正在使用 vb.net。我认为这意味着应该使用 My.Settings 而不是 Properties.Settings
4个回答

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;
        }

    }

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

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

您可以在GroupBox中的三个RadioButton的Click事件中添加以下事件处理程序(这些RadioButton的Checked属性绑定到应用程序设置):

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

即使在单选按钮未被选中的情况下点击它,它也可以工作,但需要半秒钟的时间来勾选未勾选的单选按钮。

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

规则5:不要将可点击的单选按钮绑定到数据源
我知道如果你可以将一组单选按钮绑定到枚举属性,那将是多么方便。你认为只需连接一些格式和解析事件即可将其转换回枚举类型,一切都会很好。但WinForms并不适合这样做。从现在起已经有了三个完整的版本(或者是3.5个版本?),这种情况就一直存在。这是因为事件顺序,并且这不是Microsoft可以随意更改而不会让成千上万的开发人员感到非常恼火的事情。
问题实际上归结为与其他控件的数据属性不同,单选按钮的Checked属性实际上并没有改变,直到焦点离开单选按钮。对于所有WinForms控件,焦点实际上直到在给另一个控件焦点并且新焦点控件的Click事件已触发之后才离开单选按钮。对于单选按钮,这导致如果您尝试将其绑定到数据源,则数据源中的绑定属性实际上会比单选按钮的可见状态滞后一次单击。如果您只有两个单选按钮,则数据源将完全相反于可见状态,直到您单击不触发引用这些数据源属性的操作的其他位置。这可能会使跟踪下来这个非常恼人的错误变得非常困难。我几乎以为我在幻觉。
现在,老实说,它是可以工作的。但这是最糟糕的hack之一。好吧,也许不是那么糟糕......但它肯定是一个混乱的hack。对于本应该已经可用的东西,需要进行大量的工作。据我所知,解决此问题的唯一方法,而不放弃数据绑定机制,就是基本上创建自己的RadioButton控件,并具有实际有用的属性更改和事件顺序。您可以从头开始编写一个,或者子类化RadioButton并使用自定义消息处理覆盖所有事件逻辑。

3
我可以回答你的问题:
当表单关闭时,是否需要执行一行代码以保存用户设置?
应用程序设置存储在Properties命名空间中的Settings类中。 Settings类有一个静态属性叫做Default,代表您应用程序的当前设置。因此,在您的主窗体的关闭事件中,您需要调用以下代码:
Properties.Settings.Default.Save();

... 保存设置。

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


谢谢!那让我朝着正确的方向前进了。在vb.net中,它是My.Settings而不是Properties.Settings.Default,但除此之外,它完美地工作。现在我只有一个设置,并在Load和FormClosing事件中使用表单的公共属性。 - CoderDennis
在我的电脑上,关闭时不需要保存设置。它们会自动保存。唯一的问题是我需要点击两次。 - Geoffrey

3

感谢回答。我都忘了曾经问过这个问题! - CoderDennis
不客气! 感谢点赞 :) - Ohad Schneider

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