0

我在列表视图中有一个单选按钮组。此列表视图的行(其中包含单选按钮 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 异常:

提供的类型必须是枚举。参数名称:枚举类型

有没有办法将枚举类型返回到绑定?如何告诉单选按钮它代表哪个枚举值?如何编写一个将适当的枚举值返回给绑定的函数?

希望各位大神帮忙。提前致谢!

4

3 回答 3

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;
    }
}
于 2013-03-12T15:00:40.417 回答
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 现在是正确的枚举类型。希望这可以帮助!

现在我必须弄清楚如何使单选按钮在列表视图的多行中保留选择。目前,他们在第一行中的选择会从其余行中取消选择同一组。

感谢您到目前为止的帮助。如果有人可以为我指出新问题的解决方案,那将是非常棒的!

于 2013-03-13T11:36:24.037 回答
0

建议您动态创建单选按钮,ListBox可以帮助我们做到这一点,无需转换器。此方法的优点如下:如果有一天您的枚举类发生更改,则无需更新 GUI(XAML 文件)。

该方法的步骤如下:
创建一个ListBox,并将列表框的ItemsSource设置为枚举,并将ListBox的SelectedItem绑定到selected属性。然后将创建每个 ListBoxItem 的单选按钮。

  • 第 1 步:重新定义您的枚举。
public enum EnumValueNames
{ 
   EnumValueName1, 
   EnumValueName2, 
   EnumValueName3
}

然后将以下属性添加到您的 DataContext(或 MVVM 的 ViewModel)中,该属性记录了选中的选定项目。

public EnumValueNames SelectedEnumValueName { get; set; }
  • 第 2 步:将枚举添加到 Window、UserControl 或 Grid 等的静态资源中。
    <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>
  • 第 3 步:使用列表框并将其中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

于 2020-06-05T08:34:49.897 回答