4

我在 XAML 3 中定义了菜单项(使用 WPF-MDI):

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

以及 ViewModel 中命令和当前选择的定义:

    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 个主题怎么办......有没有办法让这个代码参数化?

提前致谢。

4

1 回答 1

6

没有必要对命令进行参数化,因为绑定将执行所有操作,但如前所述,可以使用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);
    }
}

As the XAML is still verbose (and redundant!) you could take it further by binding the ItemsSource of the parent MenuItem to the enum values and then work with the ItemTemplate and ItemContainerStyle.

于 2012-02-18T01:04:32.313 回答