Привязка отмеченных пунктов меню к командам ViewModel - PullRequest
4 голосов
/ 18 февраля 2012

У меня в 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;
    }

IУ меня есть 2 вопроса (надеюсь, что это разрешено внутри одного поста):

  1. Я хочу связать свойство IsChecked в XAML со значением, которое выбрано (_selectedTheme).Я думаю, что мне нужно написать конвертер, но я не знаю, как.
  2. Я сделал 3 копии ICommands (по одной для каждой темы) ... что если бы у меня было 20 тем ... есть лиспособ сделать этот код параметризованным?

Заранее спасибо.

1 Ответ

6 голосов
/ 18 февраля 2012

Нет необходимости в параметризации команды, поскольку привязка будет делать все, но, как было отмечено, это будет возможно при использовании CommandParameter.Здесь преобразователь получит параметр enum.

Пример:

<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 со значениями перечисления, а затем работать с ItemTemplate и ItemContainerStyle.

...