问题描述
我有以下情况,这样一个类:
I have the following scenario where a class like this:
public class PetOwnerViewModel{
public PetOwnerStatus Status{get{return _petOwner.Status;}}
public ICommand SetStatusCommand {get{...}}
}
DataContext是一组类似于以下的RadioButtons:
Is DataContext to a group of RadioButtons similar to this:
<Parent DataContext="{Binding Path=PetOwner}" >
<Parent.Resources>
<myenums:PetOwnerStatus x:Key="CATLOVER">
CatLover
</myenums:PetOwnerStatus>
<myenums:PetOwnerStatus x:Key="DOGLOVER">
DogLover
</myenums:PetOwnerStatus>
</Parent.Resources>
<StackPanel>
<RadioButton Name="catLoverRadioButton"
Command="{Binding SetStatusCommand}"
CommandParameter="{StaticResource DOGLOVER}"
GroupName="PetOwnerStatusRadioButtonGroup">
Cat Lover
</RadioButton>
<RadioButton Name="dogLoverRadioButton"
Command="{Binding SetStatusCommand}"
CommandParameter="{StaticResource CATLOVER}"
GroupName="SubjectStatusRadioButtonGroup" >
Dog Lover
</RadioButton>
</StackPanel>
</Parent>
如何将View绑定到ViewModel,以便如果PetOwnerViewModel.Status返回PetOwnerStatus.CatLover,catLoverRadioButton
How do I bind the View to the ViewModel so that if PetOwnerViewModel.Status returns PetOwnerStatus.CatLover, catLoverRadioButton.IsChecked is true.
推荐答案
您可以使用数据模板使这种事情非常动态,例如
You can make this sort of thing very dynamic using data-templating, e.g.
( - 编辑)使用已经存在的 ListBox
有一个 SelectedItem
属性,请参阅 - )
(-- It makes a lot more sense to use a ListBox
which already has a SelectedItem
property, see this revised answer --)
public partial class MainWindow : Window, INotifyPropertyChanged
{
//For simplicity in put everything in the Window rather than models and view-models
public enum TestEnum { Ichi, Ni, San }
private TestEnum _EnumValue;
public TestEnum EnumValue
{
get { return _EnumValue; }
set
{
if (_EnumValue != value)
{
_EnumValue = value;
PropertyChanged.Notify(() => this.EnumValue);
}
}
}
//...
}
<ItemsControl>
<ItemsControl.Resources>
<!-- Gets the enum values -->
<ObjectDataProvider x:Key="items" MethodName="GetValues" ObjectType="{x:Type sys:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="local:MainWindow+TestEnum" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<!-- A MultiValueConverter which compares for equality -->
<vc:EqualityComparisonConverter x:Key="eqc" />
</ItemsControl.Resources>
<ItemsControl.ItemsSource>
<Binding Source="{StaticResource items}" />
</ItemsControl.ItemsSource>
<ItemsControl.ItemTemplate>
<DataTemplate>
<RadioButton Content="{Binding}" GroupName="TestEnumGroup"
Command="{x:Static local:Commands.DoStuff}" CommandParameter="{Binding}">
<RadioButton.IsChecked>
<MultiBinding Converter="{StaticResource eqc}" Mode="OneWay">
<!-- This should point to the viewmodel enum property -->
<Binding ElementName="Window" Path="DataContext.EnumValue" />
<!-- This passes the DataContext, the enum value behind the templated item, to the converter -->
<Binding />
</MultiBinding>
</RadioButton.IsChecked>
</RadioButton>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
private void DoStuff_Executed(object sender, ExecutedRoutedEventArgs e)
{
TestEnum enumval = (TestEnum)e.Parameter;
EnumValue = enumval;
}
这与原始枚举值一起运行,您可以使用显示友好的字符串来增加它们使用属性
This operates with the raw enum values, you could augment them with display friendly strings using attributes.
因为 IsChecked
绑定在所有RadioButtons上, RadioButton.GroupName
变得多余。
Because
IsChecked
is bound on all RadioButtons the RadioButton.GroupName
becomes redundant.
(我没有提供我的实现的
EqualityComparisonConverter
,因为这很可能是垃圾,但不要太难以正确地实现它,尽管)
(I did not provide my implementation of the
EqualityComparisonConverter
because it's probably crap, it shouldn't be too hard to properly implement it though)
这篇关于如何设置正确的RadioButton.IsChecked属性True通过绑定到ViewModel?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!