实际上,使用这样的转换器会破坏双向绑定,而且如上所述,您也不能将其与枚举一起使用。更好的方法是对 ListBox 使用简单的样式,如下所示:
注意:与 DrWPF.com 在他们的示例中所说的相反,不要将 ContentPresenter 放在 RadioButton 内,否则,如果您添加带有按钮或其他内容的项目,您将无法设置焦点或与之交互。这项技术解决了这个问题。此外,您需要处理文本的灰色化以及删除标签上的边距,否则将无法正确呈现。这种风格也适合你。
<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>
您现在具有单选按钮的外观和感觉,但是您可以进行双向绑定,并且可以使用枚举。方法如下...
<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>
此外,由于我们明确分离出跟踪 ListBoxItem 的样式,而不是将其放入内联,再次如其他示例所示,您现在可以从中创建新样式以基于每个项目自定义内容,例如作为间距。 (如果您只是尝试以 ListBoxItem 为目标,因为键控样式会覆盖通用控件目标,这将不起作用。)
这是一个在每个项目的上方和下方放置 6 边距的示例。 (请注意,由于上述原因,您必须如何通过 ItemContainerStyle 属性显式应用样式,而不是简单地将 ListBoxItem 定位到 ListBox 的资源部分。)
<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>