在不使用转换器的情况下将单选按钮绑定到它们的枚举值 [英] Binding Radiobuttons to their enumvalues without using a converter

查看:76
本文介绍了在不使用转换器的情况下将单选按钮绑定到它们的枚举值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在列表视图中有一个单选按钮组.此列表视图的行(其中包含单选按钮 grp 等)是一个可观察的集合.

我写的代码是这样的:

Xaml:

 </单选按钮><RadioButton Content="EnumValueName3"GroupName="RadButGrp1"IsChecked="{Binding propertyName,Mode=TwoWay,Converter={StaticResource EnumToBoolConverter},ConverterParameter=EnumValueName3}"></单选按钮>

我试图直接绑定到我的数据结构中名为 propertyName 的数据字段,该数据结构定义了包含这些值的表.对于此视图,我的 ViewModel 类中没有此字段.我这样做是为了避免跟踪我当前正在填充的集合的索引.(或者我想是这样!)

转换器:

 公共类 EnumBooleanConverter : IValueConverter{公共对象转换(对象值,类型目标类型,对象参数,System.Globalization.CultureInfo 文化){string parameterString = 参数为字符串;if (parameterString == null)返回 DependencyProperty.UnsetValue;if (value == null || Enum.IsDefined(value.GetType(), value) == false)返回 DependencyProperty.UnsetValue;object parameterValue = Enum.Parse(value.GetType(), parameterString);返回 parameterValue.Equals(value);}公共对象 ConvertBack(对象值,类型目标类型,对象参数,System.Globalization.CultureInfo 文化){string parameterString = 参数为字符串;if (parameterString == null || value.Equals(false))返回 DependencyProperty.UnsetValue;返回 Enum.Parse(targetType, parameterString);}}

问题是在Enum.Parse行的ConvertBack函数中,出现如下Argument异常:

<块引用><块引用>

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

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

希望大家帮帮忙.提前致谢!

解决方案

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

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

  • 第 1 步:重新定义您的 Enum.

public enum EnumValueNames{枚举值名称1,枚举值名称2,枚举值名称3}

然后将以下属性添加到您的 DataContext(或 MVVM 的 ViewModel)中,它会记录选中的所选项目.

public EnumValueNames SelectedEnumValueName { get;放;}

  • 第 2 步:将枚举添加到 Window、UserControl 或 Grid 等的静态资源中.

 <ObjectDataProvider MethodName="GetValues"ObjectType="{x:Type system:Enum}"x:Key="EnumValueNames"><ObjectDataProvider.MethodParameters><x:Type TypeName="local:EnumValueNames"/></ObjectDataProvider.MethodParameters></ObjectDataProvider></Window.Resources>

  • 第 3 步:使用列表框和控件模板将里面的每个项目填充为单选按钮

 <ListBox ItemsSource="{Binding Source={StaticResource EnumValueNames}}" SelectedItem="{Binding SelectedEnumValueName, Mode=TwoWay}" ><ListBox.Resources><Style TargetType="{x:Type ListBoxItem}"><Setter 属性="模板"><Setter.Value><控制模板><单选按钮内容="{TemplateBinding ContentPresenter.Content}"IsChecked="{绑定路径=IsSelected,RelativeSource={RelativeSource TemplatedParent},模式=双向}"/></控制模板></Setter.Value></Setter></风格></ListBox.Resources></列表框>

参考:https://www.codeproject.com/Articles/130137/Binding-TextBlock-ListBox-RadioButtons-to-Enums

I have a radio button group in a listview. The rows of this listview (which contain the radio button grp amongst other things) is an observable collection.

the code I have written goes something like this:

The 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>

I am trying to bind directly to the data field called propertyName in my data structure defining the table that holds these values. I do NOT have this field in my ViewModel class for this view. I did this to avoid keeping track of the index of the collection that I am currently populating. (or so i'd like to think!)

The converter:

 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);
    }
 }

The problem is that in the ConvertBack function at the Enum.Parse line, the following Argument exception occurs:

Type provided must be an Enum. Parameter name: enumType

Is there a way to return an enum type to the binding? How do I tell the radio buttons which enumeration value it represents? How do I write a function that returns the appropriate enum value to the binding?

Hoping you guys can help. Thanks in advance!

解决方案

Recommend you to create the radio buttons dynamically, ListBox can help us do that, without converters. The advantage of this method is below: if someday your enum class changes, you do not need to update the GUI (XAML file).

The steps of this method are below:
create a ListBox and set the ItemsSource for the listbox as the enum and binding the SelectedItem of the ListBox to the selected property. Then the Radio Buttons for each ListBoxItem will be created.

  • Step 1: Re-define your Enum.

public enum EnumValueNames
{ 
   EnumValueName1, 
   EnumValueName2, 
   EnumValueName3
}

Then add below property to your DataContext (or ViewModel of MVVM), which records the selected item which is checked.

public EnumValueNames SelectedEnumValueName { get; set; }

  • Step 2: add the enum to static resources for your Window, UserControl or Grid etc.

    <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>

  • Step 3: Use the List Box and Control Template to populate each item inside as Radio button

    <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>

References: https://www.codeproject.com/Articles/130137/Binding-TextBlock-ListBox-RadioButtons-to-Enums

这篇关于在不使用转换器的情况下将单选按钮绑定到它们的枚举值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆