WPF + MVVM + RadioButton:使用单一属性处理绑定
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/37790017/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF + MVVM + RadioButton : Handle binding with single property
提问by Amit Joshi
From thisand this(and other) questions on SO and many other material on internet, I understood how to bind radio button with VM.
从这个和这个(和其他)关于 SO 的问题和互联网上的许多其他材料,我了解了如何将单选按钮与 VM 绑定。
But all of them create separate property for each possible value of radio button. One question (this) is similar to my requirement but the accepted answer suggests to use ListBox instead of radio button.
但是它们都为单选按钮的每个可能值创建了单独的属性。一个问题 ( this) 与我的要求相似,但接受的答案建议使用 ListBox 而不是单选按钮。
To represent person gender (Datatype CHAR, Possible values 'M', 'F'), three properties needs to be created in VM as PersonGender, IsPersonMale, IsPersonFemale. I want to control this on only one property PersonGender. Can I do this? If yes, how?
为了表示人的性别(数据类型 CHAR,可能的值 'M'、'F'),需要在 VM 中创建三个属性,分别是 PersonGender、IsPersonMale、IsPersonFemale。我只想在一个属性 PersonGender 上控制它。我可以这样做吗?如果是,如何?
回答by user2880486
You need a converter.
你需要一个转换器。
//define this in the Window's Resources section or something similiarly suitable
<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}" />
The converter
转换器
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;
}
}
Replace null(in ConvertBack) with Binding.DoNothingif binding should not be applied in that case.
将null(in ConvertBack)替换为Binding.DoNothingif 绑定不应在这种情况下应用。
return (bool)value ? parameter : Binding.DoNothing;
回答by nkoniishvt
Use Commands (Using DelegateCommandshere)
使用命令(在此处使用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:
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>
(Didn't test the code, but this is the idea)
(没有测试代码,但这是想法)
回答by ViVi
Your requirement is possible, but you would need some additional effort to make it work. The main reason for this is RadioButton's property IsCheckedis Booleanand multiple radio buttons are separate controls and doesn't act like one. For example a ListBox.
您的要求是可能的,但您需要一些额外的努力才能使其工作。造成这种情况的主要原因是RadioButton的IsChecked属性是布尔值,并且多个单选按钮是单独的控件并且不像一个控件那样起作用。例如一个列表框。
For your requirement to work, you could use a Converter. Bind the IsCheckedof both Radiobuttons to the PersonGenderproperty in ViewModel and use a common converter and pass a parameter ‘MALE' for male radio button and 'FEMALE' for female radio button.
为了您的工作要求,您可以使用Converter。将两个 Radiobuttons的IsChecked绑定到ViewModel 中的PersonGender属性,并使用通用转换器并为男性单选按钮传递参数“MALE”,为女性单选按钮传递参数“FEMALE”。
In Converter check if parameterand PersonGenderare same and return TRUEfor that.
在转换器中检查参数和PersonGender是否相同并为此返回TRUE。
Ie. If checkbox command parameter is MALE and PersonGenderis also MALE, then the checkbox is enabled Else if checkbox command parameter is FEMALE and PersonGenderis MALE, checkbox is not enabled since false is returned.
IE。如果复选框命令参数为 MALE 且PersonGender也是 MALE,则启用复选框否则如果复选框命令参数为 FEMALE 且PersonGender为 MALE,则复选框未启用,因为返回 false。
回答by Tola Ch.
What you need to do is using IValueConverter, that convert Bool to Char and vice versa. Example True => 'M'; False => 'F'
您需要做的是使用IValueConverter,将 Bool 转换为 Char,反之亦然。示例 True => 'M'; 错误 => 'F'
In your View there are two Radio buttons. Make sure to set them in the same group name. Then You need to bind your PersonGender to only IsMale radio button only. because then IsFemale radio button is checked. the IsMale radio buton will be unchecked automatically due to same group name.
在您的视图中有两个单选按钮。确保将它们设置在相同的组名中。然后您需要将您的 PersonGender 仅绑定到 IsMale 单选按钮。因为然后 IsFemale 单选按钮被选中。由于相同的组名,IsMale 单选按钮将自动取消选中。

