在 .NET Framework 中,并没有内置 GroupBox 控件的扩展,这可能让一些开发者感到惊讶。尽管如此,可以通过自定义控件来实现这一功能。本文将介绍如何创建 CheckGroupBox 和 RadioGroupBox 控件,以及如何在 WinForm 应用程序中使用它们。
CheckGroupBox 和 RadioGroupBox控件的实现相对简单。CheckGroupBox 是从 System.Windows.Forms.GroupBox 派生的控件,它在 GroupBox 的子控件集合中添加了一个 CheckBox。同样,RadioGroupBox 也是从 GroupBox 派生的控件,它添加了一个 RadioButton。为了使 GroupBox 内的子控件能够反映 CheckBox 或 RadioButton 的选中状态,并且让 GroupBox 控件的父级能够接收到选中状态变化的通知,为这些控件添加了事件处理程序。
首先,打开 WinForm 项目,选择 "Add References..." 并添加 UIToolbox.CheckGroupBox.dll 和 UIToolbox.RadioGroupBox.dll。然后打开 Toolbox 窗口并导航到 Containers 组。现在应该能看到 CheckGroupBox 和 RadioGroupBox 列表:
就像添加其他控件一样,将这些控件拖放到 WinForm 上...
...然后像添加标准 GroupBox 一样向 GroupBox 添加控件:
CheckGroupBox 和 RadioGroupBox 的默认启用/禁用行为是不同的。从一开始,就希望 CheckGroupBox 的子控件能够随着 CheckBox 的选中状态而启用或禁用。但是,当 RadioGroupBox 的 RadioButton 被选中(选中)时,并不希望子控件的启用状态发生变化。
考虑到 CodeProject 的特性,知道会有一些开发者可能不想要这种 UI 行为,所以为这两种控件都添加了 DisableChildrenIfUnchecked 属性。
DisableChildrenIfUnchecked 默认对于 CheckGroupBox 为 true,对于 RadioGroupBox 为 false,可以在设计器中设置。
如果 WinForm 包含 RadioGroupBox控件但不包含 RadioButton 控件,可以直接在 WinForm 中像使用 CheckGroupBox 一样使用 RadioGroupBox 控件。然而,如果 WinForm 中同时包含 RadioButton 控件和 RadioGroupBox 控件,并且它们处于同一级别,会遇到广播问题。
当一个 RadioButton 从未选中变为选中时,同一级别的 CheckGroupBox 控件不会被通知选中状态的变化,反之亦然。为了解决这个问题,创建了一个从 System.Windows.Forms.Panel 派生的控件,称为 RadioButtonPanel。
要正确使用 RadioGroupBox 控件和 RadioButton 控件,请先在 WinForm 中添加一个 RadioButtonPanel 控件,然后再添加任何 RadioButton 控件或 RadioGroupBox 控件。然后,将 RadioButton 控件或 RadioGroupBox 控件添加到 RadioButtonPanel 中,而不是直接添加到 WinForm 本身。
在 RadioGroupBox 控件中看到的 RadioButton 是 RadioGroupBox 的 GroupBox 的子控件。如果创建了一个 RadioGroupBox 控件的实例并查看该实例的 Controls 属性(一个控件集合),会发现集合中包含了 RadioButton。
如果在向 WinForm 添加了 RadioGroupBox 之后,又添加了一些 RadioButton 控件,这些控件也会被添加到 GroupBox 的控件集合中。这样做的问题是,由于它们都在同一个集合中,选择 GroupBox 内的某个 RadioButton 会取消选择 GroupBox 的标题 RadioButton。
为了解决这个问题,在向 RadioGroupBox 添加 RadioButton 控件之前,先向 RadioGroupBox 添加一个 Panel 控件,然后将 RadioButton 控件添加到 Panel 中。使用这种技术,RadioButton 控件属于 Panel 而不是 RadioGroupBox,因此选择它们中的任何一个都不会影响 RadioGroupBox 的标题 RadioButton。
这些控件非常简单易用。希望其他人也能从中受益。如果遇到任何问题,请通过电子邮件与联系,将更新代码。
本文及附带文件可以自由使用,但必须满足以下条件: