我在列表视图中有一个单选按钮组。此列表视图的行(其中包含单选按钮grp)是一个可观察的集合。
我写的代码是这样的:
Xaml:
<RadioButton Content="EnumValueName1"
GroupName="RadButGrp1"
IsChecked="{Binding propertyName,Mode=TwoWay,Converter={StaticResource EnumToBoolConverter},ConverterParameter=EnumValueName1}" >
</RadioButton>
<RadioButton Content="EnumValueName2"
GroupName="RadButGrp1"
IsChecked="{Binding propertyName,Mode=TwoWay,Converter={StaticResource EnumToBoolConverter},ConverterParameter=EnumValueName2}">
</RadioButton>
<RadioButton Content="EnumValueName3"
GroupName="RadButGrp1"
IsChecked="{Binding propertyName,Mode=TwoWay,Converter={StaticResource EnumToBoolConverter},ConverterParameter=EnumValueName3}">
</RadioButton>
我试图直接绑定到我的数据结构中名为propertyName的数据字段,该数据结构定义了包含这些值的表。我的ViewModel类中没有此视图用于此视图。我这样做是为了避免跟踪我目前正在填充的集合的索引。 (或者我想想!)
转换器:
public class EnumBooleanConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string parameterString = parameter as string;
if (parameterString == null)
return DependencyProperty.UnsetValue;
if (value == null || Enum.IsDefined(value.GetType(), value) == false)
return DependencyProperty.UnsetValue;
object parameterValue = Enum.Parse(value.GetType(), parameterString);
return parameterValue.Equals(value);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string parameterString = parameter as string;
if (parameterString == null || value.Equals(false))
return DependencyProperty.UnsetValue;
return Enum.Parse(targetType, parameterString);
}
}
问题是在Enum.Parse行的ConvertBack函数中,会发生以下Argument异常:
提供的类型必须是枚举。 参数名称:enumType
有没有办法将枚举类型返回到绑定?如何告诉单选按钮它代表哪个枚举值?如何编写一个函数,为绑定返回相应的枚举值?
希望你们能提供帮助。提前谢谢!
答案 0 :(得分:0)
试试这个,这是我EnumToBoolConverter
的版本:
public class EnumToBoolConverter : BaseConverterMarkupExtension<object, bool>
{
public override bool Convert(object value, Type targetType, object parameter)
{
if (value == null)
return false;
return value.Equals(Enum.Parse(value.GetType(), (string)parameter, true));
}
public override object ConvertBack(bool value, Type targetType, object parameter)
{
return value.Equals(false) ? DependencyProperty.UnsetValue : parameter;
}
}
答案 1 :(得分:0)
好的,一旦我理解了这个概念,解决方案就相对简单了。我做了以下部分解决了我的问题。
<RadioButton Content="EnumValueName1"
GroupName="RadBtnGrp1"
IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ParentControl}},
Path=DataContext.propName,
Mode=TwoWay,
Converter={StaticResource EnumToBoolConverter},ConverterParameter=EnumValueName1}">
</RadioButton>
我的ConvertBack函数中的targetType现在是正确的枚举类型。希望这有帮助!
现在我必须弄清楚如何使radiobuttons在listview的多行中保留选择。目前,他们在第一行中的选择取消选择其余行中的相同组。
感谢您的帮助。如果有人能指出我解决新问题的解决方案真的很棒!
答案 2 :(得分:0)
建议您动态创建单选按钮,ListBox
可以帮助我们做到这一点,而无需使用转换器。此方法的优点如下:
如果某天您的枚举类更改,则无需更新GUI(XAML文件)。
此方法的步骤如下:
创建一个ListBox并将该listbox的ItemsSource设置为枚举,并将ListBox的SelectedItem绑定到selected属性。
然后将为每个ListBoxItem创建单选按钮。
public enum EnumValueNames
{
EnumValueName1,
EnumValueName2,
EnumValueName3
}
然后将以下属性添加到您的DataContext(或MVVM的ViewModel)中,该属性记录了选中的选中项。
public EnumValueNames SelectedEnumValueName { get; set; }
<Window.Resources>
<ObjectDataProvider MethodName="GetValues"
ObjectType="{x:Type system:Enum}"
x:Key="EnumValueNames">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="local:EnumValueNames" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Window.Resources>
Control Template
作为单选按钮填充其中的每个项目 <ListBox ItemsSource="{Binding Source={StaticResource EnumValueNames}}" SelectedItem="{Binding SelectedEnumValueName, Mode=TwoWay}" >
<ListBox.Resources>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<RadioButton
Content="{TemplateBinding ContentPresenter.Content}"
IsChecked="{Binding Path=IsSelected,
RelativeSource={RelativeSource TemplatedParent},
Mode=TwoWay}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.Resources>
</ListBox>
参考: https://www.codeproject.com/Articles/130137/Binding-TextBlock-ListBox-RadioButtons-to-Enums