In fact, using such a converter violates two-way binding, plus, as I said above, you cannot use this with enumerations either. The best way to do this is to use a simple style for the ListBox, like so:
Note. Contrary to what DrWPF.com pointed out in its example, do not put ContentPresenter in RadioButton, otherwise, if you add an element with content such as a button or something else, you cannot set focus or interact with it. This technique solves this is. In addition, you need to process gray text, as well as delete fields on labels, otherwise it will not display correctly. This style is also suitable for you.
<Style x:Key="RadioButtonListItem" TargetType="{x:Type ListBoxItem}" > <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="ListBoxItem"> <DockPanel LastChildFill="True" Background="{TemplateBinding Background}" HorizontalAlignment="Stretch" VerticalAlignment="Center" > <RadioButton IsChecked="{TemplateBinding IsSelected}" Focusable="False" IsHitTestVisible="False" VerticalAlignment="Center" Margin="0,0,4,0" /> <ContentPresenter Content = "{TemplateBinding ContentControl.Content}" ContentTemplate = "{TemplateBinding ContentControl.ContentTemplate}" ContentStringFormat = "{TemplateBinding ContentControl.ContentStringFormat}" HorizontalAlignment = "{TemplateBinding Control.HorizontalContentAlignment}" VerticalAlignment = "{TemplateBinding Control.VerticalContentAlignment}" SnapsToDevicePixels = "{TemplateBinding UIElement.SnapsToDevicePixels}" /> </DockPanel> </ControlTemplate> </Setter.Value> </Setter> </Style> <Style x:Key="RadioButtonList" TargetType="ListBox"> <Style.Resources> <Style TargetType="Label"> <Setter Property="Padding" Value="0" /> </Style> </Style.Resources> <Setter Property="BorderThickness" Value="0" /> <Setter Property="Background" Value="Transparent" /> <Setter Property="ItemContainerStyle" Value="{StaticResource RadioButtonListItem}" /> <Setter Property="Control.Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ListBox}"> <ItemsPresenter SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" /> </ControlTemplate> </Setter.Value> </Setter> <Style.Triggers> <Trigger Property="IsEnabled" Value="False"> <Setter Property="TextBlock.Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" /> </Trigger> </Style.Triggers> </Style> <Style x:Key="HorizontalRadioButtonList" BasedOn="{StaticResource RadioButtonList}" TargetType="ListBox"> <Setter Property="ItemsPanel"> <Setter.Value> <ItemsPanelTemplate> <VirtualizingStackPanel Background="Transparent" Orientation="Horizontal" /> </ItemsPanelTemplate> </Setter.Value> </Setter> </Style>
Now you have the appearance of the switches, but you can do two-way binding and use an enumeration. Here's how ...
<ListBox Style="{StaticResource RadioButtonList}" SelectedValue="{Binding SomeVal}" SelectedValuePath="Tag"> <ListBoxItem Tag="{x:Static l:MyEnum.SomeOption}" >Some option</ListBoxItem> <ListBoxItem Tag="{x:Static l:MyEnum.SomeOtherOption}">Some other option</ListBoxItem> <ListBoxItem Tag="{x:Static l:MyEnum.YetAnother}" >Yet another option</ListBoxItem> </ListBox>
In addition, since we explicitly separated the style that ListBoxItem tracks, rather than putting it in a row, again, as other examples showed, now you can create a new style for it to customize elements for each element, such as spacing. (This will not work if you just try to target ListBoxItem, as the key style overrides the overall management goals.)
Here is an example of placing field 6 above and below each element. (Note how you should explicitly apply a style through the ItemContainerStyle property, and not just target it with a ListBoxItem in the ListBox resource section for the reason mentioned above.)
<Window.Resources> <Style x:Key="SpacedRadioButtonListItem" TargetType="ListBoxItem" BasedOn="{StaticResource RadioButtonListItem}"> <Setter Property="Margin" Value="0,6" /> </Style> </Window.Resources> <ListBox Style="{StaticResource RadioButtonList}" ItemContainerStyle="{StaticResource SpacedRadioButtonListItem}" SelectedValue="{Binding SomeVal}" SelectedValuePath="Tag"> <ListBoxItem Tag="{x:Static l:MyEnum.SomeOption}" >Some option</ListBoxItem> <ListBoxItem Tag="{x:Static l:MyEnum.SomeOtherOption}">Some other option</ListBoxItem> <ListBoxItem Tag="{x:Static l:MyEnum.YetAnother}" >Ter another option</ListBoxItem> </ListBox>