使用 ApplicationSettings 存储 WinForms RadioButtons 的 Checked 属性

发布于 2024-07-22 07:00:53 字数 449 浏览 3 评论 0原文

我有一个包含 3 个单选按钮的 WinForms 对话框。 我使用 ApplicationSettings 绑定每个 RadioButton 控件的 Checked 属性,但它没有执行我期望的操作。 现在,我必须单击每个单选按钮两次才能检查它,并且所选单选按钮不会被保留。

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

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

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

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

I have a WinForms dialog box that contains 3 radio buttons. I am using ApplicationSettings to bind the Checked property of each of these RadioButton controls, but it doesn't do what I am expecting it to do. Now I have to click each radio button twice before it gets checked and the selected radio button is not being persisted.

Is there a line of code I need to execute when the form is closed that saves the user settings?

How do I eliminate the need for 2x clicking on the radio buttons?

Is there a better way to persist this type of user setting? I do have a public property on the dialog box class that gets/sets an enum value based on which radio button is checked, but I didn't see an easy way of binding that property to a user setting.

Edit: Should have specified that I'm using vb.net. I think that means My.Settings instead of Properties.Settings.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

我很坚强 2024-07-29 07:00:53

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

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

您可以将以下事件处理程序添加到 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

它可以工作,即使未选中的 RadioButton 需要半秒的时间。点击后检查。

两年前(2008 年)在 幸存 WinForms 数据绑定 发表在 Turbulent Intelect 博客上(谢谢 ohadsc 提供的链接) :

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

我知道如果你有的话那该多好
可以绑定你的一堆收音机
按钮到枚举属性。 我真的
做。 你认为你只是要去
连接一些格式化和解析事件
翻译回您的枚举,并且
一切都会好起来。 那就太糟糕了
方便的话,如果真的有效的话。 但
WinForms 不适合这个。
现在有 3 个完整版本(或者是 3.5
发布?),情况就是如此。
这是因为事件顺序,
不是MS可以去的
切换不会造成数千
的开发人员感到非常厌烦
关闭。

问题实际上归结为
事实上,与其他控件的数据不同
属性,a 的 Checked 属性
单选按钮实际上并没有改变
直到焦点离开单选按钮。
与所有 WinForms 控件一样
焦点实际上并没有离开收音机
按钮,直到焦点被赋予后
另一个控制,事实上直到
新的 Click 事件之后
集中控制已启动。 结果
这与广播有关
按钮,如果你尝试绑定到
他们,你的绑定属性
数据源实际上会落后于你
单选按钮的视觉状态减一
单击
。 如果你只有两台收音机
按钮,数据源将是
与可见状态完全相反,
直到你点击其他地方
不会触发以下操作
引用那些数据源
特性。 这可以使这成为
真正令人恼火的错误要追踪。
我差点以为自己出现了幻觉。

现在,老实说,有可能
让它起作用。 但它是最笨拙的
曾经拼凑过的拼凑。 好吧也许
没那么糟糕...但是很乱
肯定是黑客攻击。 这需要大量的工作
为了一些真正应该的事情
已经可用。 尽我所能
告诉,解决这个问题的唯一方法
问题而不放弃
数据绑定机制是
本质上是制作你自己的RadioButton
控制,通过属性改变和
实际有用的事件顺序。
您可以从头开始编写一个,
或RadioButton 的子类并覆盖
所有事件逻辑都带有自定义
消息处理。

I answer this part of your question:

How do I eliminate the need for 2x clicking on the radio buttons?

You can add the following event handler to the Click event of each of the three RadioButtons (of which the Checked properties are bound to Application Settings) in your GroupBox:

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

It works, even though it takes a half-second for an unckecked RadioButton to be checked after you click it.

The reason for the problem was explained two years ago (in 2008) in section 5 of the Surviving WinForms Databinding post on the Turbulent Intelect blog (Thank you, ohadsc, for the link):

Rule 5: Don't bind to clickable Radio Buttons

I know how great it would be if you
could just bind your bunch of radio
buttons to an enum property. I really
do. You think you're just going to
hook up some Format and Parse events
to translate back to your enum, and
all will be well. It would be so darn
convenient, if it actually worked. But
WinForms just isn't cut out for this.
For 3 full releases now (or is it 3.5
releases?), this has been the case.
It's because of the event order, which
is not something that MS can go
switching up without causing thousands
of developers to get really cheesed
off.

The problem really comes down to the
fact that unlike other controls' data
properties, the Checked property of a
radio button doesn't actually change
until focus leaves the radio button.
And as with all WinForms controls the
focus doesn't actually leave the radio
button until after focus is given to
another control, and in fact not until
after the Click event of the newly
focused control has fired. The result
of this, as it pertains to radio
buttons, is that if you try to bind to
them, the bound properties in your
datasource will actually lag your
radio buttons' visual state by one
click
. If you have just two radio
buttons, the datasource will be
exactly opposite the visible state,
until you click somewhere else that
doesn't trigger an action that
references those datasource
properties. Which can make this a
really infuriating bug to track down.
I almost thought I was hallucinating.

Now, in all honesty, it's possible to
make it work. But it is the kludgiest
kludge that ever kludged. Okay maybe
it's not that bad... but it's a messy
hack for sure. It takes a lot of work
for something that really should
already be available. As near as I can
tell, the only way to solve this
problem without giving up the
databinding mechanism is to
essentially make your own RadioButton
control, with a property change and
event order that is actually useful.
You can either write one from scratch,
or sub-class RadioButton and override
all the event logic with custom
message handling.

抚你发端 2024-07-29 07:00:53

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

    }

Thanks to Geoffrey Van Wyk and ohadsc (for the link), I came up with the following custom control. It's basically a custom frame that will implement Geoffrey's code automatically on all radiobuttons contained in it. The advantage is that you can now use ApplicationSettings to bind the checked property of the control, and it will work as it is supposed to.

Here's my c# code to make the custom control:

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

    }
风铃鹿 2024-07-29 07:00:53

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

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

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

Properties.Settings.Default.Save();

... 来保存设置。

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

I can answer this part of your question:

Is there a line of code I need to execute when the form is closed that saves the user settings?

Application settings are stored in your Settings class, in the Properties namespace. The Settings class has a static property called Default, which represents the current settings for your application. So in your main form's Closing event, you call:

Properties.Settings.Default.Save();

... to save the settings.

Likewise you can get to the settings programatically using the setting's name: Properties.Settings.Default.MyRadioButtonState (or whatever you've called it).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文