我继承了一个使用RadioButtonList
的项目,该项目继承自ListBox
。它被取消了(目前无法找到链接),并包含RadioButtonList.cs(包含六个依赖属性)和RadioButtonList.xaml(它只是样式和控件模板)。
此控件用于超过一百个地方。它会导致问题,因为它不是一个完整和专业的控制。问题,如焦点问题,键盘导航等。 (见评论。)
在过去几年的不同时间进行了大量研究后,似乎这种控制确实没有必要。所需的只是在一组单选按钮上设置GroupName
属性。并且,使用RadioButtonList
控件的唯一原因是通过继承的ListBox
来帮助对选项列表进行数据绑定。
1)这种控制真的有必要吗?还有更好的方法吗?
2)是否有专业控制,开源或其他方式,这将使我能够在没有头痛的情况下获得数据绑定的好处? (我们使用Infragistics和DevExpress,但我不熟悉这些套件提供的所有控件。)
1a)这种控制真的有必要吗?
1b)有更好的方法吗?
ListBox
,ItemsControl
或其他任何东西派生,然后创建样式和模板是创建此控件的唯一方法;因此,没有更好的方法。2)是否有专业控制......
ListBoxEdit
与RadioListBoxEditStyleSettings
。所有答案都表明不需要创建RadioButtonList
控件。但是,如果您需要多个单选按钮列表,那么在创建样式和控件模板以及数据模板时,您最终会得到一组代码工件,可称为单选按钮列表 - 控制。因此,在我看来,RadioButtonList
是必要的。
此外,我的理解是在早期的WPF CTP中删除了RadioButtonList
。我可以理解,因为对这种控制的需求有限,很容易创建。
2)是否有专业控制......
ListBoxEdit
与RadioListBoxEditStyleSettings
。我所拥有的RadioButtonList
是他答案的最终结果。虽然我擅长创建自定义控件,但我宁愿让第三方组件制造商(如Infragistics和DevExpress)创建并支持这样的基本控件。
答案 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
项目的外观。例如,您可能希望:
RadioButton
项目的“项目符号”周围的边距; RadioButton
内容。创建您自己的实现(很可能源自ListBox
)允许您轻松添加这些功能,即使您已经在应用程序中使用了无线电列表。这可以通过上面的技术完成,虽然它可能需要附加行为或一些附加属性,在这种情况下,你最终会有一些碎片设计。
第三方解决方案
是否有专业控制,开放源代码或其他方式,这将使我能够在没有头痛的情况下获得数据绑定的好处?
这不是一个不常见的用例,我毫不怀疑有一些实现浮动。有些可能在开源框架中,有些可能是从开源应用程序中提取的。至于第三方实现,我知道Actipro在其共享WPF库中提供了RadioButtonList
,它包含在所有WPF组件中。当我最后检查时,它本身不可用。但是,它支持我上面列出的所有附加功能。
答案 1 :(得分:1)
在我看来,你不需要这个控制。 您只需使用.Net ListBox即可实现所有现有功能。
答案 2 :(得分:1)
我只能告诉你,DevExpress使用ListBoxEdit
和RadioListBoxEditStyleSettings
代表一组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.IsCheckedProperty
和ContentControl.ContentProperty
的绑定。虽然这些部件只是样板代码,但在键盘行为的实现方面可能会有更多的努力。