WPF Radiobutton (два) (привязка к логическому значению) - PullRequest
38 голосов
/ 29 июля 2010

У меня есть свойство типа boolean, представленное флажком.

Я хочу изменить это на две радиокнопки, которые связывают одно и то же свойство, представляя значение true / false.

Как это можно сделать?

Ответы [ 6 ]

74 голосов
/ 29 июля 2010
<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
}
9 голосов
/ 29 июля 2010

Вы можете использовать преобразователь значения, который возвращает логическое значение:

С этим преобразователем свяжите одно свойство Checkbox.IsChecked с логическим значением без преобразователя и одно свойство CheckBox.IsChecked с преобразователем.,Это должно сработать.

Вот код для такого конвертера.Я скопировал его из здесь и добавил несколько строк кода.Там вы найдете больше информации о.

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

Чтобы использовать его, объявите его в разделе ресурсов.

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

И используйте его в привязке как статический ресурс:

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

Обратите внимание, что конвертер является лишь простым примером.Реализуйте это аккуратно, если вы хотите использовать его в производительном коде.Я не проверял это.Оставьте комментарий, если он не работает.

8 голосов
/ 26 декабря 2015

Стандартный подход к связыванию имеет неприятный побочный эффект, так как установщик привязки запускается как «невыбранный» при загрузке пользовательского интерфейса.Так что если у вас есть код для обработки кликов пользователя в установщике для вашего bool, он будет выполнять некоторые странные вещи, такие как запуск сеттера в «false», даже если вы привязали его к «истинному» bool.

Я справился с этим с помощью конвертера, используемого специально для переключателей:

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

В ваших ресурсах:

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

В вашем 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}}" />
3 голосов
/ 02 февраля 2014

Этого можно достичь без конвертера, если установить для свойства GroupName двух переключателей одинаковое значение (поэтому можно проверить только один). Затем установите IsChecked одной из переключателей на «True» и привяжите IsChecked другой к своему логическому значению. Переключение переключателей приведет к изменению логического значения, однако изменение логического значения на False не приведет к проверке другого переключателя.

Спасибо, Влад

2 голосов
/ 05 февраля 2014

Вот решение о том, как привязать переключатели к любому типу (перечисление, логическое значение, строка, целое число и т. Д.) С примером кода:

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

0 голосов
/ 01 марта 2017

Упрощенная версия ragunathan 's ответ .

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