【问题标题】:How can I uncheck radiobuttons in C# while still allowing only the first radiobutton to be tabbable?如何在 C# 中取消选中单选按钮,同时仍然只允许第一个单选按钮可选项卡?
【发布时间】:2020-02-28 20:57:42
【问题描述】:

不确定标题是否有意义,所以这里是完整的上下文:

我正在用 C# 编写代码。 我制作了一个包含多个用户控件的应用程序,每个控件都有许多文本框和单选按钮。 所有单选按钮都放置在一组 2 个的面板中,如下所示:

[ <label> O <radiobutton1text> O <radiobutton2text> ]

(而第一个单选按钮的 TabStop = true,第二个的 TabStop = false)

当切换到这样的面板时,只有 radiobutton1text 被聚焦,当点击 LeftArrow 键时,radiobutton2text 被选中。这就是我们想要的结果。

为了使 UserControl 在第二次(及以上)时间加载更快,我没有关闭它,而是在每次内容需要更改时用不同的 UserControl 替换它。 但这引发了一个问题:当 UserControl X 打开时,在它上面我打开 UserControl Y 然后返回 X,文本框和单选按钮仍然具有第一次打开 UserControl X 时的内容. (我需要在替换 UserControl 后重置文本框和单选按钮的内容)。

所以我创建了一个循环所有控件并清空其内容的函数。 问题是,当我取消选中此函数中的单选按钮(并将它们的 TabStop 状态恢复为 true)时,第二个单选按钮是可选项卡在我检查其中一个之后然后调用该函数,而'在通过这个函数之前。

功能:

        public void BackToMain(object sender, EventArgs e)
        {
            // Go through all controls and empty each TextBox, RichTextBox, RadioButton or ComboBox.
            int parentControlsCount = Controls.Count - 1;
            for (int i = parentControlsCount; i >= 0; i--)
            {
                if (Controls[i].HasChildren == true)
                {
                    int childrenControlsCount = Controls[i].Controls.Count - 1;
                    for (int j = childrenControlsCount; j >= 0; j--)
                    {
                        var controlType = Controls[i].Controls[j].GetType().ToString();

                        switch (controlType)
                        {
                            case "System.Windows.Forms.TextBox":
                            case "System.Windows.Forms.RichTextBox":
                                Controls[i].Controls[j].Text = null;
                                break;

                            case "System.Windows.Forms.RadioButton":
                                // Restore both properties to default value
                                ((RadioButton)Controls[i].Controls[j]).Checked = false;
                                if (j == 1)
                                    ((RadioButton)Controls[i].Controls[j]).TabStop = true;
                                else if (j == 2)
                                    ((RadioButton)Controls[i].Controls[j]).TabStop = false;
                                break;

                            case "System.Windows.Forms.ComboBox":
                                ((ComboBox)Controls[i].Controls[j]).SelectedIndex = -1;
                                break;
                        }
                    }
                }
            }
        }

我做错了什么?

【问题讨论】:

  • 您可能应该将Reset() 方法添加到您从内部执行此操作的用户控件,设置预定义的初始状态。您只需在需要时调用此方法。顺便说一句,如果在其他地方使用类似的东西,您的伪递归过程无论如何都需要重新设计。
  • @Jimi 嗯,这个功能来自所说的UserControl。我认为这里的问题在于逻辑。为第一个单选按钮手动启用 TabStop 意味着当用户单击第二个单选按钮时(运行此函数后),第一个单选按钮的 TabStop 状态不会改变,直到用户选择它然后再次选择第二个单选按钮。至少这就是这里发生的事情。即使知道这一点,我也想不出一个好的对策,除了可能创建一个 CheckedChanged 事件并从那里做事。我没有在其他地方使用这种方法,但是有什么问题呢?
  • 您已经注意到 TabStop 功能 也在其他地方(不是由您)处理。已经给出了这个 clearing 过程并不完全是最先进的提示(顺便说一句,一个名为 BackToMain 的方法不建议使用内部方法 GetType(),在内部也没有使用)。使用带有 2 个单选按钮的面板对其进行测试。在Panel.Leave 事件中,写入:radioButton1.Checked = false; radioButton2.Checked = false; radioButton1.TabStop = true; radioButton2.TabStop = false;。向窗体添加几个可聚焦的控件并按 Tab。

标签: c# tabs radio-button tabstop


【解决方案1】:

我最终在每秒钟单选按钮的 CheckedChange 上应用了这个粗俗的 hack 函数:

        private void DisableTabStopOnCheckedChange(object sender, EventArgs e)
        {
            // Assume the following STR:
            // 1. In any radiobutton panel, select any radiobutton (without ever invoking BackToMain function in the first post);
            // 2. Invoke the BackToMain function;
            // 3. In the same radiobutton panel as in step #1, click the second radiobutton.
            // Normally, without this function, if the user will now cycle through the controls using the Tab key, both the first and second radiobuttons will be tabbable,
            // and that's because in the BackToMain function we reset their Checked and TabStop properies, and that's something that should be handled automatically by the control itself.
            // Doing it manually means that for the *first time* selecting the second radiobutton, the first one's TabStop state won't update, which means both radiobuttons
            // will have the TabStop state set to true, causing both to be tabbable.
            // This is a gross hack to fix this by disabling TabStop on the first radio button if the second one is checked and the first one's TabStop state
            // is true (this should happen only after BackToMain has been invoked).
            if (((RadioButton)sender).Checked)
            {
                var firstRadioButton = ((RadioButton)sender).Parent.Controls[1];
                if (((RadioButton)firstRadioButton).TabStop == true)
                {
                    ((RadioButton)firstRadioButton).TabStop = false;
                }
            }
        }

我知道,这不是一个很好的解决方案。但它有效。

【讨论】:

    猜你喜欢
    • 2014-01-04
    • 2018-08-01
    • 1970-01-01
    • 2015-12-17
    • 2015-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多