2011-06-06 29 views
2

我有以下的場景是這樣一類:如何通過綁定到ViewModel來設置正確的RadioButton.IsChecked屬性爲真?

public class PetOwnerViewModel{ 
public PetOwnerStatus Status{get{return _petOwner.Status;}} 

    public ICommand SetStatusCommand {get{...}} 
} 

是DataContext的類似於這樣一組單選按鈕的:

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

如何綁定觀對視圖模型,這樣,如果PetOwnerViewModel.Status返回PetOwnerStatus.CatLover,catLoverRadioButton.IsChecked爲true。

回答

3

使用數據模板可以使這種事情變得非常動態,例如,

( - 編輯:這讓很多更有意義使用ListBox已經具有SelectedItem性質,見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; 
} 

此操作與原始的枚舉值,你可以擴大他們與顯示友好的字符串使用屬性。

因爲IsChecked綁定在所有的RadioButton上,所以RadioButton.GroupName變得多餘。

我沒有提供我的執行EqualityComparisonConverter的,因爲它可能是廢話,這不應該太難正確實現它雖然

+0

十分感謝,我已經得到了我的解決方案的工作,它的要好得多,擁有一樣東西是相對於其他可能的枚舉值靈活。 – Grokodile 2011-06-07 00:16:55

+0

這有點複雜,但確實爲更大的枚舉付出了代價。很高興幫助:) – 2011-06-07 00:24:50

2

有WPF中一個相當知名的錯誤與數據綁定和RadioButtons。這是我通常會做的方式:

<StackPanel> 
    <RadioButton 
     Content="Cat Lover" 
     Command="{Binding SetStatusCommand}" 
     CommandParameter="{x:Static local:PetOwnerStatus.CatLover}" 
     IsChecked="{Binding Path=Status, Mode=TwoWay, Converter={StaticResource equalityConverter}, ConverterParameter={x:Static local:PetOwnerStatus.CatLover}}" 
     GroupName="1" /> 

    <RadioButton 
     Content="Dog Lover" 
     Command="{Binding SetStatusCommand}" 
     CommandParameter="{x:Static local:PetOwnerStatus.DogLover}" 
     IsChecked="{Binding Path=Status, Mode=TwoWay, Converter={StaticResource equalityConverter}, ConverterParameter={x:Static local:PetOwnerStatus.DogLover}}" 
     GroupName="2" /> 
</StackPanel> 

的equalityConverter需要一個枚舉的ConverterParameter,並確定它的綁定值(狀態)。如果值相等,則轉換器返回true,然後將IsChecked設置爲true。上面的IsChecked綁定表達式本質上是說「如果ConverterParameter中指定的值等於Status的值,則將IsChecked設置爲true」。

此外,您可以通過定義名稱空間並使用x:Static來使用實際的枚舉值,而無需創建單獨的資源。

請注意,您必須爲每個RadioButton提供一個不同的GroupName,否則WPF錯誤會自行顯示並且綁定被破壞。

更多詳細信息請訪問: How to bind RadioButtons to an enum?

相關問題