How to bind RadioButtons to an enum?

前端 未结 9 2082
日久生厌
日久生厌 2020-11-22 03:21

I\'ve got an enum like this:

public enum MyLovelyEnum
{
    FirstSelection,
    TheOtherSelection,
    YetAnotherOne
};

I got a property in

相关标签:
9条回答
  • 2020-11-22 04:06

    This work for Checkbox too.

    public class EnumToBoolConverter:IValueConverter
    {
        private int val;
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            int intParam = (int)parameter;
            val = (int)value;
    
            return ((intParam & val) != 0);
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            val ^= (int)parameter;
            return Enum.Parse(targetType, val.ToString());
        }
    }
    

    Binding a single enum to multiple checkboxes.

    0 讨论(0)
  • 2020-11-22 04:06

    Based on the EnumToBooleanConverter from Scott. I noticed that the ConvertBack method doesn't work on the Enum with flags code.

    I've tried the following code:

    public class EnumHasFlagToBooleanConverter : IValueConverter
        {
            private object _obj;
            public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                _obj = value;
                return ((Enum)value).HasFlag((Enum)parameter);
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                if (value.Equals(true))
                {
                    if (((Enum)_obj).HasFlag((Enum)parameter))
                    {
                        // Do nothing
                        return Binding.DoNothing;
                    }
                    else
                    {
                        int i = (int)_obj;
                        int ii = (int)parameter;
                        int newInt = i+ii;
                        return (NavigationProjectDates)newInt;
                    }
                }
                else
                {
                    if (((Enum)_obj).HasFlag((Enum)parameter))
                    {
                        int i = (int)_obj;
                        int ii = (int)parameter;
                        int newInt = i-ii;
                        return (NavigationProjectDates)newInt;
    
                    }
                    else
                    {
                        // do nothing
                        return Binding.DoNothing;
                    }
                }
            }
        }
    

    The only thing that I can't get to work is to do a cast from int to targetType so I made it hardcoded to NavigationProjectDates, the enum that I use. And, targetType == NavigationProjectDates...


    Edit for more generic Flags Enum converter:

        public class FlagsEnumToBooleanConverter : IValueConverter {
            private int _flags=0;
            public object Convert(object value, Type targetType, object parameter, string language) {
                if (value == null) return false;
                _flags = (int) value;
                Type t = value.GetType();
                object o = Enum.ToObject(t, parameter);
                return ((Enum)value).HasFlag((Enum)o);
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, string language)
            {
                if (value?.Equals(true) ?? false) {
                    _flags = _flags | (int) parameter;
                }
                else {
                    _flags = _flags & ~(int) parameter;
                }
                return _flags;
            }
        }
    
    0 讨论(0)
  • 2020-11-22 04:10

    You can create the radio buttons dynamically, ListBox can help you do that, without converters, quite simple.

    The concrete steps are below:

    • create a ListBox and set the ItemsSource for the listbox as the enum MyLovelyEnum and binding the SelectedItem of the ListBox to the VeryLovelyEnum property.
    • then the Radio Buttons for each ListBoxItem will be created.
    • Step 1: 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="MyLovelyEnum">
                <ObjectDataProvider.MethodParameters>
                    <x:Type TypeName="local:MyLovelyEnum" />
                </ObjectDataProvider.MethodParameters>
            </ObjectDataProvider>
        </Window.Resources>
    
    • Step 2: Use the List Box and Control Template to populate each item inside as Radio button
        <ListBox ItemsSource="{Binding Source={StaticResource MyLovelyEnum}}" SelectedItem="{Binding VeryLovelyEnum, 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>
    

    The advantage is: if someday your enum class changes, you do not need to update the GUI (XAML file).

    References: https://brianlagunas.com/a-better-way-to-data-bind-enums-in-wpf/

    0 讨论(0)
提交回复
热议问题