34

Let's imagine that I have:

<RadioButton GroupName="Group1" IsChecked="{Binding Path=RadioButton1IsChecked}" />
<RadioButton GroupName="Group1" IsChecked="{Binding Path=RadioButton2IsChecked}" />

And then in my data source class I have:

public bool RadioButton1IsChecked { get; set; }
public bool RadioButton2IsChecked { get; set; }
public enum RadioButtons { RadioButton1, RadioButton2, None }
public RadioButtons SelectedRadioButton
{
    get
    {
        if (this.RadioButtonIsChecked) 
            return RadioButtons.RadioButton1;
        else if (this.RadioButtonIsChecked) 
            return RadioButtons.RadioButton2;
        else 
            return RadioButtons.None;
     }
}

Can I somehow bind my radio buttons directly to SelectedRadioButton property? I really need RadioButton1IsChecked and RadioButton2IsChecked properties only to calculate the selected radiobutton.

oxfn
  • 6,590
  • 2
  • 26
  • 34
Bogdan Verbenets
  • 25,686
  • 13
  • 66
  • 119
  • this [blog post](http://blogs.msdn.com/b/mthalman/archive/2008/09/04/wpf-data-binding-with-radiobutton.aspx) may help – Jake Berger Feb 09 '12 at 16:22
  • See [my answer on a related question](http://stackoverflow.com/questions/9145606/how-can-i-reduce-this-wpf-boilerplate-code/9145914#9145914), it should help. The `SelectedItem` binds to the property of interest. – H.B. Feb 09 '12 at 18:39
  • 3
    I prefer: http://stackoverflow.com/questions/397556/how-to-bind-radiobuttons-to-an-enum – quetzalcoatl Aug 08 '12 at 13:28
  • 1
    http://stackoverflow.com/a/2908885/986 – Mark Ingram Feb 18 '15 at 11:21
  • Possible duplicate of [How to bind RadioButtons to an enum?](https://stackoverflow.com/questions/397556/how-to-bind-radiobuttons-to-an-enum) – John Jul 19 '17 at 16:20

4 Answers4

64

Declare an enumeration similar to:

enum RadioOptions {Option1, Option2}

XAML:

<RadioButton IsChecked="{Binding SelectedOption, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static local:RadioOptions.Option1}}"/>
<RadioButton IsChecked="{Binding SelectedOption, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static local:RadioOptions.Option2}}"/>

Converter class:

public class EnumBooleanConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value.Equals(parameter);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return ((bool)value) ? parameter : Binding.DoNothing;
    }
}
Usman Zafar
  • 1,919
  • 1
  • 15
  • 11
  • 1
    What is the functionnal difference with the accepted answer? – Jerther Mar 02 '16 at 21:34
  • 11
    @Jerther: the accepted answer takes a string parameter and converts it to an enum. This one accepts an enum value directly, which is a much better idea as it will fail to compile if a parameter is incorrect. – Artfunkel Feb 13 '17 at 20:57
20
<RadioButton GroupName="Group1" IsChecked="{Binding Path=SelectedRadioButton, Converter={StaticResource EnumBooleanConverter}, ConverterParameter=RadioButton1}" />
<RadioButton GroupName="Group1" IsChecked="{Binding Path=SelectedRadioButton, Converter={StaticResource EnumBooleanConverter}, ConverterParameter=RadioButton2}" />
public enum RadioButtons { RadioButton1, RadioButton2, None }
public RadioButtons SelectedRadioButton {get;set;}

 public class EnumBooleanConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var ParameterString = parameter as string;
            if (ParameterString == null)
                return DependencyProperty.UnsetValue;

            if (Enum.IsDefined(value.GetType(), value) == false)
                return DependencyProperty.UnsetValue;

            object paramvalue = Enum.Parse(value.GetType(), ParameterString);
            return paramvalue.Equals(value);
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var ParameterString = parameter as string;
            var valueAsBool = (bool) value;

            if (ParameterString == null || !valueAsBool)
            {
                try
                {
                    return Enum.Parse(targetType, "0");
                }
                catch (Exception)
                {
                    return DependencyProperty.UnsetValue;
                }
            }
            return Enum.Parse(targetType, ParameterString);
        }
    }
krijesta
  • 3,155
  • 1
  • 14
  • 3
Bogdan Verbenets
  • 25,686
  • 13
  • 66
  • 119
  • Wouldn't this set the `SelectedRadioButton` value to `RadioButtons.None` (by executing `return Enum.Parse(targetType, "0"); `) whenever any of the radio buttons' `IsChecked` property is set to `false`? – O. R. Mapper Sep 22 '12 at 08:43
5

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

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

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

public enum RadioButtons
{ 
   RadioButton1, 
   RadioButton2, 
   None
}
  • 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="RadioButtons">
            <ObjectDataProvider.MethodParameters>
                <x:Type TypeName="local:RadioButtons" />
            </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 RadioButtons}}" SelectedItem="{Binding SelectedRadioButton, 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>

Now, enjoy~

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

Bravo Yeung
  • 8,654
  • 5
  • 38
  • 45
-1

XAML:

<RadioButton IsChecked="{Binding Path=SelectedOption, UpdateSourceTrigger=PropertyChanged}">Option1</RadioButton>
<RadioButton IsChecked="{Binding Path=SelectedOption, UpdateSourceTrigger=PropertyChanged, Converter={v:NotBoolenConverter}}">Option2</RadioButton>

Converter:

public class NotBoolenConverter : IValueConverter
    {
        public NotBoolenConverter()
        {
        }

        public override object Convert(
            object value,
            Type targetType,
            object parameter,
            CultureInfo culture)
        {
            bool output = (bool)value;
            return !output;
        }

        public override object ConvertBack(
            object value,
            Type targetType,
            object parameter,
            CultureInfo culture)
        {
            bool output = (bool)value;
            return !output;
        }
    }

Works with 2 radio buttons, by binding one to the opposite of the other.

user1336827
  • 1,728
  • 2
  • 15
  • 30