I inherited a project that uses a RadioButtonList
which inherits from a ListBox
. It was taken off the web (currently cannot find a link to), and contains RadioButtonList.cs (which contains six dependency properties) and RadioButtonList.xaml (which is just styles and control templates).
This control is used in over a hundred places. It causes problems because it is not a complete and professional control. Problems such as, focus issues, keyboard navigation, and so on. (See comments.)
After much research at different times over the last couple years, it seems that this control is really not necessary. All that is needed is to set the GroupName
property on a group of radio-buttons. And, the only reason why a RadioButtonList
control is used is to help with data-binding a list of options through the inherited ListBox
.
1) Is this control really necessary? Is there a better way?
2) Is there a professional control, open-source or otherwise, that will allow me to get the benefits of data-binding without the headaches? (We use Infragistics and DevExpress, but I am not familiar with all the controls these suites offer.)
1a) Is this control really necessary?
1b) Is there a better way?
ListBox
, ItemsControl
, or whatever then creating styles and templates is the only way to create this control; therefore, no there is no better way.2) Is there a professional control...
ListBoxEdit
with the RadioListBoxEditStyleSettings
.All the answers indicate that creating a RadioButtonList
control is not necessary. Yet, if you need more than a couple lists of radio buttons, by the time you create the styles and control templates and maybe data template, you will end up with a collection of code artifacts that can be called a radio-button-list-control. Therefore, in my opinion, a RadioButtonList
is necessary.
Moreover, my understanding is a RadioButtonList
was dropped in an early WPF CTP. Which I can understand, because of the limited need for such a control that can easily be created.
2) Is there a professional control...
ListBoxEdit
with the RadioListBoxEditStyleSettings
.The RadioButtonList
that I have is the end-result of his answer. While I am good at creating custom-controls, I rather let third-party component makers, such as Infragistics and DevExpress, create and support a basic control like this one.
Is this control really necessary? Is there a better way?
As @lawc points out, no, it is not necessary. It may, however, be preferable, depending on what level of flexibility you desire. A reusable style is easy enough to create, but doing it "correctly" is a bit more involved than simply setting a custom ItemTemplate
.
Using Styles
An ItemsControl
in WPF will wrap its items in appropriate containers. Each of the selector controls in core WPF overrides the logic which determines whether an item is capable of serving as its own container, as well as the factory code which produces new item containers. A ListBox
, for example, will wrap each of its items in a ListBoxItem
(unless the item itself is already a ListBoxItem
). The style applied to these containers can be set for the parent ItemsControl
via the ItemContainerStyle
property. This differs from the ItemTemplate
property, which allows you to control the appearance of the item within the container. More specifically, it overrides the content template applied to the ContentPresenter
within the container.
Since a RadioButton
does not derive from ListBoxItem
, simply setting the ItemTemplate
will produce a list of RadioButton
controls embedded within ListBoxItem
controls, which means they will still have the same selection chrome normally associated with ListBox
controls, and possibly some layout and focus oddities. This is probably not what you want.
Instead, override the ItemContainerStyle
and use it to assign a custom ListBoxItem
template which embeds a RadioButton
. You can probably get away with not setting the GroupName
property at all, which eliminates possible name collisions. Instead, just establish a two-way binding between the RadioButton.IsChecked
property and the templated parent's ListBoxItem.IsSelected
property.
In order to use this technique conveniently, one generally creates a Style
resource (available application-wide) which can be applied to the appropriate ListBox
instances, and which sets the ItemContainerStyle
. Alternatively, you can make the container style available as a global resource and set that on your ListBox
instances. Either way, you need to set a property.
Using a Custom Control
While WPF evangelists often recite the philosophy of preferring custom styles over custom controls, in practice this is not always convenient. You may find it more convenient to create a RadioButtonList
which extends the ListBox
control, and then give it a default style which automatically applies the custom style described above. This gets you out of manually assigning the list style or container style on every ListBox
instance, but it's not a huge win.
But maybe you want a bit more control over the appearance of the RadioButton
items. For instance, you may want to:
RadioButton
item;RadioButton
content for items which are not selected.Creating your own implementation, most likely derived from ListBox
, allows you to add these features easily, even after you are already using your radio list across your application. This could be done with the technique above too, though it may require an attached behavior or some attached properties, in which case you end up with a somewhat fragmented design.
Third-Party Solutions
Is there a professional control, open-source or otherwise, that will allow me to get the benefits of data-binding without the headaches?
This is not an uncommon use case, and I have no doubt there are some implementations floating around. Some may be in open source frameworks, and some may be extracted from open source applications. As for third-party implementations, I do know that Actipro ships a RadioButtonList
in their Shared WPF library, which is included with all of their WPF components. When last I checked, it was not available on its own. It does, however, support all of the additional features I listed above.
I can only tell you that DevExpress uses a ListBoxEdit
with a RadioListBoxEditStyleSettings
to represent a group of RadioButtons. Practically it is the same as your control you are using, but i think it provides better functionality and is well tested. A RadioButton is not provided by DevExpress and in my application i use the Default RadionButton-Control provided by WPF/Silverlight.
You use the RadioListBoxEdit of DevExpress as follows:
<dxe:ListBoxEdit SelectedItem={Binding CheckItem, Mode=TwoWay}>
<dxe:ListBoxEdit.StyleSettings>
<dxe:RadioListBoxEditStyleSettings />
</dxe:ListBoxEdit.StyleSettings>
</dxe:ListBoxEdit>
More information about the ListBoxEdit of DevExpress can be found here
In my opinion you don't need this control. You can simply use .Net ListBox to achieve all your existing functionality.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With