WPF中是否需要基于`ListBox`的自定义`RadioButtonList`?

时间:2013-09-28 04:00:22

标签: wpf custom-controls radiobuttonlist

我继承了一个使用RadioButtonList的项目,该项目继承自ListBox。它被取消了(目前无法找到链接),并包含RadioButtonList.cs(包含六个依赖属性)和RadioButtonList.xaml(它只是样式和控件模板)。

此控件用于超过一百个地方。它会导致问题,因为它不是一个完整和专业的控制。问题,如焦点问题,键盘导航等。 (见评论。)

在过去几年的不同时间进行了大量研究后,似乎这种控制确实没有必要。所需的只是在一组单选按钮上设置GroupName属性。并且,使用RadioButtonList控件的唯一原因是通过继承的ListBox来帮助对选项列表进行数据绑定。

1)这种控制真的有必要吗?还有更好的方法吗?

2)是否有专业控制,开源或其他方式,这将使我能够在没有头痛的情况下获得数据绑定的好处? (我们使用Infragistics和DevExpress,但我不熟悉这些套件提供的所有控件。)

我的答案

1a)这种控制真的有必要吗?

  • 如果您只需要一个单选按钮列表,则不需要此控件。
  • 如果您的应用程序使用了许多单选按钮列表,则可以使用此控件。
  • 如果您在不同的应用程序中使用单选按钮列表,则可能需要此控件。

1b)有更好的方法吗?

  • 我说从ListBoxItemsControl或其他任何东西派生,然后创建样式和模板是创建此控件的唯一方法;因此,没有更好的方法。

2)是否有专业控制......

  • 当然,ListBoxEditRadioListBoxEditStyleSettings

关于答案的评论

所有答案都表明不需要创建RadioButtonList控件。但是,如果您需要多个单选按钮列表,那么在创建样式和控件模板以及数据模板时,您最终会得到一组代码工件,可称为单选按钮列表 - 控制。因此,在我看来,RadioButtonList是必要的。

此外,我的理解是在早期的WPF CTP中删除了RadioButtonList。我可以理解,因为对这种控制的需求有限,很容易创建。

关于接受的答案的评论

2)是否有专业控制......

  • 当然,ListBoxEditRadioListBoxEditStyleSettings

最后评论Mike Strobel的答案

我所拥有的RadioButtonList是他答案的最终结果。虽然我擅长创建自定义控件,但我宁愿让第三方组件制造商(如Infragistics和DevExpress)创建并支持这样的基本控件。

4 个答案:

答案 0 :(得分:4)

  

这种控制真的有必要吗?还有更好的方法吗?

正如@lawc指出的那样,不,没有必要。但是,根据您所希望的灵活程度,它可能更为可取。可重用的样式很容易创建,但“正确”执行它比简单地设置自定义ItemTemplate更为复杂。

使用样式

WPF中的ItemsControl会将其项目包装在适当的容器中。核心WPF中的每个选择器控件都会覆盖确定项目是否能够作为其自己的容器的逻辑,以及生成新项目容器的工厂代码。例如,ListBox会将其每个项目包装在ListBoxItem中(除非项目本身已经是ListBoxItem)。可以通过ItemsControl属性为父ItemContainerStyle设置应用于这些容器的样式。这与ItemTemplate属性不同,后者允许您控制容器中项的外观。更具体地说,它会覆盖应用于容器中ContentPresenter的内容模板。

由于RadioButton并非来自ListBoxItem,因此只需设置ItemTemplate即可生成嵌入RadioButton控件中的ListBoxItem个控件列表,这意味着它们仍然具有通常与ListBox控件关联的相同选择镶边,可能还有一些布局和焦点奇怪。这可能不是你想要的。

相反,覆盖ItemContainerStyle并使用它来指定嵌入ListBoxItem的自定义RadioButton模板。您可能完全没有设置GroupName属性,从而消除了可能的名称冲突。相反,只需在RadioButton.IsChecked属性和模板化父级ListBoxItem.IsSelected属性之间建立双向绑定。

为了方便地使用这种技术,通常会创建一个Style资源(可用的应用程序范围),可以应用于相应的ListBox实例,并设置ItemContainerStyle 。或者,您可以将容器样式作为全局资源使用,并在ListBox实例上进行设置。无论哪种方式,您都需要设置属性。

使用自定义控件

虽然WPF布道者经常背诵自定义风格优于自定义控件的理念,但实际上这并不总是方便。您可能会发现创建RadioButtonList 扩展 ListBox控件更方便,然后为其提供一个自动应用上述自定义样式的默认样式。这使您无法在每个ListBox实例上手动分配列表样式或容器样式,但这不是一个巨大的胜利。

但也许你想要更多地控制RadioButton项目的外观。例如,您可能希望:

  1. 调整每个RadioButton项目的“项目符号”周围的边距;
  2. 调整项目符号相对于内容的垂直对齐方式;
  3. 支持水平和垂直方向;
  4. 自动停用未选中项目的RadioButton内容。
  5. 创建您自己的实现(很可能源自ListBox)允许您轻松添加这些功能,即使您已经在应用程序中使用了无线电列表。这可以通过上面的技术完成,虽然它可能需要附加行为或一些附加属性,在这种情况下,你最终会有一些碎片设计。

    第三方解决方案

      

    是否有专业控制,开放源代码或其他方式,这将使我能够在没有头痛的情况下获得数据绑定的好处?

    这不是一个不常见的用例,我毫不怀疑有一些实现浮动。有些可能在开源框架中,有些可能是从开源应用程序中提取的。至于第三方实现,我知道Actipro在其共享WPF库中提供了RadioButtonList,它包含在所有WPF组件中。当我最后检查时,它本身不可用。但是,它支持我上面列出的所有附加功能。

答案 1 :(得分:1)

在我看来,你不需要这个控制。 您只需使用.Net ListBox即可实现所有现有功能。

  1. 使用ListBox.ItemsSource,您可以绑定选项集合
  2. 指定包含RadioButton的ListBox.ItemTemplate,在此模板中,您可以将视图模型属性数据绑定到RadioButton.GroupName

答案 2 :(得分:1)

我只能告诉你,DevExpress使用ListBoxEditRadioListBoxEditStyleSettings代表一组RadioButtons。实际上它与您使用的控件相同,但我认为它提供了更好的功能并且经过了充分测试。 DevExpress不提供RadioButton,在我的应用程序中,我使用WPF / Silverlight提供的Default RadionButton-Control。

您使用DevExpress的RadioListBoxEdit,如下所示:

<dxe:ListBoxEdit SelectedItem={Binding CheckItem, Mode=TwoWay}>
  <dxe:ListBoxEdit.StyleSettings>
    <dxe:RadioListBoxEditStyleSettings />
  </dxe:ListBoxEdit.StyleSettings>
</dxe:ListBoxEdit>

有关DevExpress的ListBoxEdit的更多信息,请访问here

答案 3 :(得分:0)

恕我直言,来自ItemsControl的控件将是最干净的方法。

然后你可能会覆盖

  • IsItemItsOwnContainerOverride()return item is RadioButton;
  • GetContainerForItemOverride()return每个项目new RadioButton()
  • PrepareContainerForItemOverride()设置ToggleButton.IsCheckedPropertyContentControl.ContentProperty的绑定。

虽然这些部件只是样板代码,但在键盘行为的实现方面可能会有更多的努力。