WPF + MVVM + RadioButton: обрабатывать привязку с одним свойством

Отэтот а такжеэтот (и другие) вопросы по SO и многим другим материалам в интернете, я понял, как связать радиокнопку с VM.

Но все они создают отдельное свойство для каждого возможного значения переключателя. Один вопрос (этот) аналогично моему требованию, но принятый ответ предлагает использовать ListBox вместо переключателя.

Чтобы представить пол человека (тип данных CHAR, возможные значения 'M', 'F'), в VM необходимо создать три свойства: PersonGender, IsPersonMale, IsPersonFemale. Я хочу контролировать это только на одном свойстве PersonGender. Я могу это сделать? Если да, то как?

 nkoniishvt13 июн. 2016 г., 14:51
Команды созданы для MVVM, привязка к команде из пользовательского интерфейса - это то, что вам следует делать, если вы хотите иметь приложение, совместимое с MVVM. Взгляните на учебник, как этот:codeproject.com/Articles/238657/How-to-use-Commands-in-WPF
 Amit Joshi13 июн. 2016 г., 14:47
@nkoniishvt: выглядит интересно; попробую это. Но все еще не полностью приемлемо. Переключатель представляет собой пользовательский ввод и отображает текстовое поле или поле со списком; не действие как командная кнопка. Использование команды для обработки ввода / отображения дозы выглядит неправильно.
 nkoniishvt13 июн. 2016 г., 14:43
Поместите Команду на каждый RadioButton (то же самое) и передайте их значение в качестве параметра

Ответы на вопрос(4)

DelegateCommands Вот)

VM:

public enum Genders {
    Female,
    Male
}
public YourVMClass {
    public Genders SelectedGender {get; set;}

    private DelegateCommand _cmdSelectGender;

    public DelegateCommand CmdSelectGender {
        get { return _cmdSelectGender ?? (_cmdSelectGender = new DelegateCommand(SelectGender)); }
    }

    private void SelectGender(Object parameter) {
        SelectedGender = (Genders)parameter;
    }
}

XAML:

<Window.Resources>
    <ObjectDataProvider x:Key="listOfGenders" MethodName="GetValues"
                        ObjectType="{x:Type System:Enum}">
        <ObjectDataProvider.MethodParameters>
            <x:Type TypeName="loca:Genders"/>
        </ObjectDataProvider.MethodParameters>
    </ObjectDataProvider>
</Window.Resources>

<ItemsControl ItemsSource="{Binding Source={StaticResources listOfGenders}}">
    <ItemsControl.ItemTemplate>
        <RadioButton GroupName="Genders" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type MainWindow}}, Path=DataContext.CmdSelectGender}" CommandParameter="{Binding}"/>
    </ItemsControl.ItemTemplate>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

(Не тестировал код, но это идея)

Решение Вопроса

Вам нужен конвертер.

        //define this in the Window's Resources section or something similiarly situitable
        <local:GenderConverter x:Key="genderConverterKey" />


        <RadioButton Content="M" IsChecked="{Binding Gender, Converter={StaticResource ResourceKey=genderConverterKey}, ConverterParameter=M}" />
        <RadioButton Content="F" IsChecked="{Binding Gender, Converter={StaticResource ResourceKey=genderConverterKey}, ConverterParameter=F}" />

Конвертер

public class GenderConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return ((string)parameter == (string)value);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return (bool)value ? parameter : null;        
    }
}
 Peter M01 сент. 2017 г., 14:19
В конвертере нет ничего, что могло бы связать его с типом данных Gender. Таким образом, вы можете переименовать его, чтобы сделать его конвертером общего назначения.
 Amit Joshi22 июн. 2016 г., 12:06
замещатьноль (в ConvertBack) сBinding.DoNothing если обязательство не должно применяться в этом случае.возвращаемое (bool) значение? параметр: Binding.DoNothing;

но вам нужно будет приложить дополнительные усилия, чтобы оно заработало. Основной причиной этого являетсяПереключательСобственностьПроверено являетсялогический и несколько переключателей являются отдельными элементами управления и не действуют как один. Например, ListBox.

Для вашего требования к работе, вы можете использоватьконвертер, ПривязатьПроверено обеих радиокнопок наPersonGender свойство в ViewModel и использовать общий конвертер и передать параметр «MALE» для переключателя «мужчина» и «FEMALE» для переключателя «женщина».

В конвертере проверьте, еслипараметр а такжеPersonGender одинаковы и возвращаютсяПРАВДА для этого.

То есть. Если флажок параметр команды MALE иPersonGender также MALE, тогда флажок включен, если параметр команды checkbox имеет значение FEMALE иPersonGender имеет значение MALE, флажок не установлен, поскольку возвращается false.

IValueConverter, которые конвертируют Bool в Char и наоборот. Пример True => 'M'; False => 'F'

В вашем представлении есть две кнопки радио. Удостоверьтесь, чтобы установить их в том же имени группы. Затем вам нужно привязать ваш PersonGender только к переключателю IsMale. потому что тогда переключатель IsFemale проверяется. радио-кнопка IsMale будет автоматически отключена из-за того же имени группы.

Ваш ответ на вопрос