2012-02-18 72 views
3

我在XAML(使用WPF-MDI)定義3菜單項:綁定檢查菜單項視圖模型命令

<MenuItem Header="_Generic" Name="Generic" ToolTip="Generic Visual Studio designer theme" 
      Command="{Binding Path=SelectGenericTheme}"/> 
<MenuItem Header="_Luna" Name="Luna" ToolTip="Blue Windows XP theme" 
      Command="{Binding Path=SelectLunaTheme}"/> 
<MenuItem Header="_Aero" Name="Aero" ToolTip="Windows Vista/7 theme" 
      Command="{Binding Path=SelectAeroTheme}"/> 

而在視圖模型的命令和當前選擇的定義:

public enum ESelectedTheme 
    { 
     Generic, 
     Luna, 
     Aero 
    } 

    ESelectedTheme _selectedTheme; 

    ICommand _selectGenericThemeCommand; 
    public ICommand SelectGenericThemeCommand 
    { 
     get { return _selectGenericThemeCommand ?? (_selectGenericThemeCommand = new RelayCommand(param => SelectGenericTheme(), 
      param => true)); } 
    } 

    void SelectGenericTheme() 
    { 
     _selectedTheme = ESelectedTheme.Generic; 
    } 


    ICommand _selectLunaThemeCommand; 
    public ICommand SelectLunaThemeCommand 
    { 
     get 
     { 
      return _selectLunaThemeCommand ?? (_selectLunaThemeCommand = new RelayCommand(param => SelectLunaTheme(), 
       param => true)); 
     } 
    } 

    void SelectLunaTheme() 
    { 
     _selectedTheme = ESelectedTheme.Luna; 
    } 


    ICommand _selectAeroThemeCommand; 
    public ICommand SelectAeroThemeCommand 
    { 
     get 
     { 
      return _selectAeroThemeCommand ?? (_selectAeroThemeCommand = new RelayCommand(param => SelectAeroTheme(), 
       param => true)); 
     } 
    } 

    void SelectAeroTheme() 
    { 
     _selectedTheme = ESelectedTheme.Aero; 
    } 

我有2個問題(希望是允許一個門柱內側):

  1. 我想在XAML的財產器isChecked綁定到值,我被選中(_selectedTheme)。我想我需要寫一個轉換器,但我不知道如何。
  2. 我做了3個ICommands副本(每個主題一個)......如果我有20個主題......有沒有辦法讓這個代碼參數化?

在此先感謝。

+2

您可以指定['CommandParameter'](http://msdn.microsoft.com/en-us/library/system.windows.controls.menuitem.com和parameter_aspx),並詢問如何參數化命令?你是否一直忽略'param => ...'而不想如何使用它? – 2012-02-18 00:47:19

+0

使用參數我的意思是有3個命令只使用1個命令(但我會檢查CommandParameter是如何工作的,這可能有幫助)。感謝您的評論。 – 2012-02-18 00:48:57

+0

使用'RelayCommand(T)'作爲謂詞傳入'true'是毫無意義的,因爲它默認以這種方式開始。 – 2012-02-18 01:09:02

回答

5

沒有必要參數化命令,因爲綁定會做所有事情,但正如注意到它可能使用CommandParameter。這裏轉換器將獲得枚舉參數。

一個例子:

<MenuItem Header="_Description" IsCheckable="True" 
     IsChecked="{Binding Path=DisplayMode_Current, 
          Converter={StaticResource EnumToBooleanConv}, 
          ConverterParameter=Description}" /> 
<MenuItem Header="_Web-Page" IsCheckable="True" 
     IsChecked="{Binding Path=DisplayMode_Current, 
          Converter={StaticResource EnumToBooleanConv}, 
          ConverterParameter=WebPage}" /> 

轉換器可以是這個樣子:

public class EnumToBooleanConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     // You could also directly pass an enum value using {x:Static}, 
     // then there is no need to parse 
     string parameterString = parameter as string; 
     if (parameterString == null) 
      return DependencyProperty.UnsetValue; 

     if (Enum.IsDefined(value.GetType(), value) == false) 
      return DependencyProperty.UnsetValue; 

     object parameterValue = Enum.Parse(value.GetType(), parameterString); 

     return parameterValue.Equals(value); 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     string parameterString = parameter as string; 
     if (parameterString == null) 
      return DependencyProperty.UnsetValue; 

     return Enum.Parse(targetType, parameterString); 
    } 
} 

由於XAML仍然是冗長(和多餘的!),你可以把它進一步結合的ItemsSource將父項MenuItem設置爲枚舉值,然後使用ItemTemplateItemContainerStyle

+0

I將需要一些時間來嘗試這...謝謝你的努力! – 2012-02-18 01:07:33

+0

我猜SelectedTheme(ViewModel中的屬性)應該是一個依賴屬性?如果是這樣......我仍然要學習很多關於WPF的知識。 – 2012-02-18 01:35:12

+1

@MichelKeijzers:不,永遠不要在虛擬機中使用依賴屬性,你知道[INPC](http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx)和[如何實現它](http://msdn.microsoft.com/en-us/library/ms229614.aspx),對不對?它應該只是一個實現綁定通知接口的普通屬性。 – 2012-02-18 01:37:36