WPF Radiobutton (two) (binding to boolean value)

WpfBindingRadio ButtonBoolean

Wpf Problem Overview


I have a property of type boolean presented with checkbox.

I want to change that to two radiobuttons that bind on the same property presenting the value true/false.

How can that be done?

Wpf Solutions


Solution 1 - Wpf

<RadioButton GroupName="Group1" 
             IsChecked="{Binding PropertyValue}" Content="Yes" />
<RadioButton GroupName="Group1"  Content="No" 
             IsChecked="{Binding PropertyValue, 
                         Converter={StaticResource BoolInverterConverter}}" />

public class BoolInverterConverter : IValueConverter
{
	#region IValueConverter Members

	public object Convert(object value, Type targetType, object parameter,
        System.Globalization.CultureInfo culture)
	{
		if (value is bool)
		{
			return !(bool)value;
		}
		return value;
	}

	public object ConvertBack(object value, Type targetType, object parameter, 
        System.Globalization.CultureInfo culture)
	{
        if (value is bool)
        {
            return !(bool)value;
        }
        return value;
	}

	#endregion
}

Solution 2 - Wpf

The standard binding approach has the unfortunate side effect of firing the binding setter as "unselected" whenever the UI is loaded. So if you've got code to handle the user's clicks in the setter for your bool, it will do some weird stuff like fire the setter to "false" even though you've bound it to a "true" bool.

I got around this with a converter used specifically for radio buttons:

public class BoolRadioConverter : IValueConverter
{
	public bool Inverse { get; set; }

	public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
	{
		bool boolValue = (bool) value;

		return this.Inverse ? !boolValue : boolValue;
	}

	public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
	{
		bool boolValue = (bool)value;

		if (!boolValue)
		{
			// We only care when the user clicks a radio button to select it.
			return null;
		}

		return !this.Inverse;
	}
}

In your resources:

<converters:BoolRadioConverter x:Key="BoolRadioConverter" />
<converters:BoolRadioConverter x:Key="InverseBoolRadioConverter" Inverse="True" />

In your xaml:

<RadioButton
	Content="True option"
	GroupName="radioGroup1"
	IsChecked="{Binding MyProperty,
						Converter={StaticResource BoolRadioConverter}}" />
<RadioButton
	Content="False option"
	GroupName="radioGroup2"
	IsChecked="{Binding MyProperty,
						Converter={StaticResource InverseBoolRadioConverter}}" />

Solution 3 - Wpf

You can use a value-converter that reverts the boolean value:

With that converter, bind one Checkbox.IsChecked-property to the boolean value without the converter and one CheckBox.IsChecked-property with the converter. This should do the trick.

Here the code for such a converter. I have copied it from http://www.codeproject.com/KB/WPF/OppositeBoolConverter.aspx">here</a> and added some lines of code. There you will find more information about.

public class BoolToOppositeBoolConverter : IValueConverter {
    public object Convert(object value, Type targetType, object parameter,System.Globalization.CultureInfo culture) {
        if (targetType != typeof(bool)) {
            throw new InvalidOperationException("The target must be a boolean");
        }
        if (null == value) {
            return null;
        }
                    return !(bool)value;
    }

    public object ConvertBack(object value, Type targetType, object parameter,System.Globalization.CultureInfo culture) {
        if (targetType != typeof(bool)) {
            throw new InvalidOperationException("The target must be a boolean");
        }
        if (null == value) {
            return null;
        }
        return !(bool)value;
    }
} 

To use it, declare it in the resource-section.

 <local:BoolToOppositeBoolConverter x:Key="BoolToOppositeBoolConverter_ValueConverter"/>

And the use it in the binding as a static resource:

<CheckBox IsChecked="{Binding YourProperty}" />
<CheckBox IsChecked="{Binding YourProperty,Converter={StaticResource BoolToOppositeBoolConverter_ValueConverter}}" />

Please note, the converter is only a simple example. Implement it neatly if you want to use it in productive code. I have not tested it. Make a comment if its not working.

Solution 4 - Wpf

You can achieve this without a converter if you set the GroupName property of two radio button to the same value (so only one can be checked at the time). Then, set IsChecked of one radio button to "True", and bind IsChecked of another to your Boolean. Switching radio buttons will change the Boolean value, however, changing the Boolean value to False will not check the other radio button.

Thanks, Vlad

Solution 5 - Wpf

Here is the solution on how to bind radio buttons to any type (enumeration, Boolean, string, integer, etc.) with the sample code:

http://www.codeproject.com/Tips/720497/Binding-Radio-Buttons-to-a-Single-Property

Solution 6 - Wpf

When using MVVMLight and DataContext is set in XAML as:

DataContext="{Binding <Your ViewModel property name>, Source={StaticResource Locator}}" 

BoolInverterConverter causes Stack Overflow second time the window gets opened.

The work around is to remove DataContext from XAML and do it in code in window constructor after InitializeComponent():

DataContext = ServiceLocator.Current.GetInstance<Your View Model class>();

After some testing it was not enough - Stack Overflow error could pop up randomly when clicking on radio button. The solution which worked for me - instead of the converter use another property for other radio button in a group:

public bool Is9to1 { get; set; }
public bool Is1to9 { get { return !Is9to1; } set { Is9to1 = !value; } } 

in XAML:

   <RadioButton GroupName="Is9to1" IsChecked="{Binding Is1to9}"/>
   <RadioButton GroupName="Is9to1" IsChecked="{Binding Is9to1}"/>

Solution 7 - Wpf

Simplified version of ragunathan's answer.

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) =>
	Convert(value);

public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) =>
	Convert(value);

private object Convert(object value) => 
	value is bool ? !(bool)value : value;

Solution 8 - Wpf

Little upgrade of RandomEngy's answer if you want your bool nullable (for no default value/Checked Radiobutton)

public class BoolRadioConverter : IValueConverter
{
    public bool Inverse { get; set; }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        bool? boolValue = (bool?)value;

        return this.Inverse ? !boolValue : boolValue;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        bool? boolValue = (bool?)value;

        if (boolValue != null && (bool)!boolValue)
        {
            // We only care when the user clicks a radio button to select it.
            return null;
        }

        return !this.Inverse;
    }
}

and the rest is the same as his answer.

Solution 9 - Wpf

From The answer of Mr-RandomQC everything works fine. But when I click another radio in the same group. Then the opposite radio will show a Red box around the radio button.

I changed the code a little bit from his answer to return Binding.DoNothing instead of return null like this.

public class BoolRadioConverter : IValueConverter
{
    public bool Inverse { get; set; }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        bool boolValue = (bool)value;

        return this.Inverse ? !boolValue : boolValue;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        bool boolValue = (bool)value;

        if (!boolValue)
        {
            // Return Binding.DoNothing instead of Return null
            return Binding.DoNothing;
        }

        return !this.Inverse;
    }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionno9View Question on Stackoverflow
Solution 1 - WpfRagunathanView Answer on Stackoverflow
Solution 2 - WpfRandomEngyView Answer on Stackoverflow
Solution 3 - WpfHCLView Answer on Stackoverflow
Solution 4 - WpfvotrubacView Answer on Stackoverflow
Solution 5 - WpfvotrubacView Answer on Stackoverflow
Solution 6 - WpfPavel PopovView Answer on Stackoverflow
Solution 7 - WpfoddRavenView Answer on Stackoverflow
Solution 8 - WpfMr-RandomQCView Answer on Stackoverflow
Solution 9 - Wpfice thailandView Answer on Stackoverflow