WPF中的数据绑定单选按钮列表
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WPF中的数据绑定单选按钮列表相关的知识,希望对你有一定的参考价值。
我有一个数据对象的选项列表,我想使用一个单选按钮列表,以允许用户选择一个,只有一个。功能类似于数据绑定组合框,但采用单选按钮格式。
愚蠢的我,我以为这将是内置的,但没有。你怎么做呢?
基本上,在查看谷歌搜索结果之后,我开始使用an MSDN discussion thread where Dr. WPF provided an answer提供的信息,该文章讨论了使ListBox样式化的问题。然而,当列表框被禁用时,背景是一种烦人的颜色,我无法摆脱我的生活,直到我读到the MSDN example of the ListBox ControlTemplate,它显示了正在踢我背景屁股的秘密边框元素。
所以,这里的最终答案是这种风格:
<Style x:Key="RadioButtonList" TargetType="{x:Type ListBox}">
<!-- ControlTemplate taken from MSDN http://msdn.microsoft.com/en-us/library/ms754242.aspx -->
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
<Setter Property="MinWidth" Value="120"/>
<Setter Property="MinHeight" Value="95"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBox">
<Border Name="Border" Background="Transparent"
BorderBrush="Transparent"
BorderThickness="0"
CornerRadius="2">
<ScrollViewer Margin="0" Focusable="false">
<StackPanel Margin="2" IsItemsHost="True" />
</ScrollViewer>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="Border" Property="Background"
Value="Transparent" />
<Setter TargetName="Border" Property="BorderBrush"
Value="Transparent" />
</Trigger>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="{x:Type ListBoxItem}" >
<Setter Property="Margin" Value="2" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border Name="theBorder" Background="Transparent">
<RadioButton Focusable="False" IsHitTestVisible="False"
IsChecked="{TemplateBinding IsSelected}">
<ContentPresenter />
</RadioButton>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
</Style>
它为ListBox和Items提供了ControlTemplate和样式。它被这样使用:
<ListBox Grid.Column="1" Grid.Row="0" x:Name="TurnChargeBasedOnSelector" Background="Transparent"
IsEnabled="{Binding Path=IsEditing}"
Style="{StaticResource RadioButtonList}"
ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:MainForm}}, Path=DataContext.RampTurnsBasedOnList}"
DisplayMemberPath="Description" SelectedValuePath="RampTurnsBasedOnID"
SelectedValue="{Binding Path=RampTurnsBasedOnID, NotifyOnValidationError=True, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}"/>
我花在WPF上的时间越多,我就越认为它使得琐碎的疯狂困难和疯狂的琐事。请享用。斯科特
将列表框绑定到ListBox的ItemsSource,其中包含具有属性Name的对象列表(这可以更改)
<ListBox Name="RadioButtonList">
<ListBox.ItemTemplate >
<DataTemplate >
<RadioButton GroupName="radioList" Tag="{Binding}" Content="{Binding Name}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
重要的GroupName =“radioList”
我是通过将ValueConverter
转换为enum
的bool
完成的。通过将单选按钮表示的枚举值传递为ConverterParameter
,转换器将返回是否应检查此单选按钮。
<Window.Resources>
<Converters:EnumConverter x:Key="EnumConverter" />
</Window.Resources>
<RadioButton IsChecked="{Binding Path=MyEnum, Mode=TwoWay,
Converter={StaticResource EnumConverter},
ConverterParameter=Enum1}"}
Content="Enum 1" />
<RadioButton IsChecked="{Binding Path=MyEnum, Mode=TwoWay,
Converter={StaticResource EnumConverter},
ConverterParameter=Enum2}"}
Content="Enum 2" />
EnumConverter
定义如下:
public class EnumConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (targetType.IsAssignableFrom(typeof(Boolean)) && targetType.IsAssignableFrom(typeof(String)))
throw new ArgumentException("EnumConverter can only convert to boolean or string.");
if (targetType == typeof(String))
return value.ToString();
return String.Compare(value.ToString(), (String)parameter, StringComparison.InvariantCultureIgnoreCase) == 0;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (targetType.IsAssignableFrom(typeof(Boolean)) && targetType.IsAssignableFrom(typeof(String)))
throw new ArgumentException("EnumConverter can only convert back value from a string or a boolean.");
if (!targetType.IsEnum)
throw new ArgumentException("EnumConverter can only convert value to an Enum Type.");
if (value.GetType() == typeof(String))
{
return Enum.Parse(targetType, (String)value, true);
}
//We have a boolean, as for binding to a checkbox. we use parameter
if ((Boolean)value)
return Enum.Parse(targetType, (String)parameter, true);
return null;
}
}
请注意,我没有数据绑定到枚举列表以生成单选按钮,我已经手动完成了它们。如果你想通过绑定填充单选按钮列表,我认为你需要将IsChecked
绑定更改为绑定到当前值和radio的枚举值的MultiBinding
,因为你不能在ConverterParameter
上使用绑定。
超级简单,MVVM友好,利用DataTemplates进行类型化。 XAML:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<DataTemplate DataType="{x:Type local:Option}">
<RadioButton Focusable="False"
IsHitTestVisible="False"
Content="{Binding Display}"
IsChecked="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=ListBoxItem}}">
</RadioButto以上是关于WPF中的数据绑定单选按钮列表的主要内容,如果未能解决你的问题,请参考以下文章
C# WPF:当单选按钮显示为图像时,数据网格中的单选按钮分组不起作用