WPF + MVVM + RadioButton:处理与单个属性的绑定

时间:2016-06-13 12:36:04

标签: c# wpf mvvm data-binding radio-button

从关于SO的thisthis(及其他)问题以及互联网上的许多其他资料,我了解了如何将单选按钮与VM绑定。

但是所有这些都为单选按钮的每个可能值创建了单独的属性。一个问题(this)类似于我的要求,但接受的答案建议使用ListBox而不是单选按钮。

要表示人物性别(数据类型CHAR,可能的值' M',' F'),需要在VM中创建三个属性,如PersonGender,IsPersonMale,IsPersonFemale。 我想只在一个属性PersonGender上控制它。 我可以这样做吗?如果是,怎么样?

4 个答案:

答案 0 :(得分:13)

你需要一个转换器。

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

如果在这种情况下不应用绑定,请将nullConvertBack)替换为Binding.DoNothing

return (bool)value ? parameter : Binding.DoNothing;

答案 1 :(得分:2)

使用命令(在此处使用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>

(没有测试代码,但这是想法)

答案 2 :(得分:1)

您的要求是可能的,但您需要做一些额外的努力才能使其发挥作用。主要原因是 RadioButton 的属性 IsChecked 布尔,多个单选按钮是单独的控件,并且不像一个。例如ListBox。

根据您的要求,您可以使用转换器。 将两个Radiobuttons的 IsChecked 绑定到ViewModel中的 PersonGender 属性并使用通用转换器并为男性单选按钮传递参数'MALE',为女性单选按钮传递'FEMALE'

在转换器中检查参数 PersonGender 是否相同,并返回 TRUE

IE中。如果checkbox命令参数为MALE且 PersonGender 也为MALE,则启用该复选框 否则,如果checkbox命令参数为FEMALE且 PersonGender 为MALE,则不会启用复选框,因为返回false。

答案 3 :(得分:0)

您需要做的是使用IValueConverter,将Bool转换为Char,反之亦然。 示例True =&gt; &#39; M&#39 ;;错误=&gt; &#39; F&#39;

在您的视图中有两个单选按钮。确保将它们设置在相同的组名称中。 然后,您只需要将PersonGender绑定到仅IsMale单选按钮。 因为然后检查IsFemale单选按钮。由于相同的组名,IsMale无线电按钮将自动取消选中。