10

我继承了一个项目,该项目使用RadioButtonList从 a 继承的 a ListBox。它是从网上撤下的(目前找不到链接),并包含 RadioButtonList.cs(包含六个依赖属性)和 RadioButtonList.xaml(只是样式和控件模板)。

该控件用于一百多个地方。它会导致问题,因为它不是完整且专业的控件。诸如焦点问题、键盘导航等问题。(看评论。)

经过过去几年不同时间的大量研究,似乎这种控制确实没有必要。所需要的只是GroupName在一组单选按钮上设置属性。而且,使用控件的唯一原因RadioButtonList是帮助通过继承的ListBox.

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

2)是否有专业的控制,开源或其他方式,可以让我获得数据绑定的好处而不会让人头疼?(我们使用 Infragistics 和 DevExpress,但我不熟悉这些套件提供的所有控件。)

我的答案

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

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

1b)有更好的方法吗?

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

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

  • 当然,ListBoxEditRadioListBoxEditStyleSettings.

关于答案的评论

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

此外,我的理解是RadioButtonList在早期的 WPF CTP 中被丢弃。我可以理解,因为对这种可以轻松创建的控件的需求有限。

关于已接受答案的评论

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

  • 当然,ListBoxEditRadioListBoxEditStyleSettings.

最后评论 Mike Strobel 的回答

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

4

4 回答 4

4

这种控制真的有必要吗?有没有更好的办法?

正如@lawc 指出的那样,不,没有必要。但是,这可能更可取,具体取决于您想要的灵活性级别。可重用的样式很容易创建,但“正确”地进行操作比简单地设置自定义ItemTemplate.

使用样式

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

由于 aRadioButton不是从 派生的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未选择项目的内容。

创建您自己的实现(很可能源自ListBox)允许您轻松添加这些功能,即使您已经在整个应用程序中使用您的单选列表。这也可以使用上面的技术来完成,尽管它可能需要附加的行为或一些附加的属性,在这种情况下,您最终会得到一个有点碎片化的设计。

第三方解决方案

是否有专业的控制,开源或其他方式,可以让我获得数据绑定的好处而不会令人头疼?

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

于 2013-10-04T17:48:32.233 回答
1

在我看来,你不需要这种控制。您可以简单地使用 .Net ListBox 来实现所有现有功能。

  1. 使用 ListBox.ItemsSource 您可以数据绑定您的选项集合
  2. 指定包含 RadioButton 的 ListBox.ItemTemplate,在此模板中,您可以将视图模型属性数据绑定到 RadioButton.GroupName
于 2013-10-01T01:12:23.203 回答
1

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

您使用 DevExpress 的 RadioListBoxEdit 如下:

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

关于 DevExpress 的 ListBoxEdit 的更多信息可以在这里找到

于 2013-10-07T18:23:31.047 回答
0

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

那么你可能会覆盖

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

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

于 2013-10-07T14:45:33.493 回答