0

I see lots of people asking questions similar to mine, but so far I haven't been able to put the pieces together to solve my problem.

I have a certain enum type (let's call it MyCustomEnum) which I'd like to use to create the list of choices in a ContextMenu. I'd like the menu items to be checkable, and have the checked MenuItem bound to a static setting the application uses (a property we'll call MyCustomEnumSetting on the settings class MyCustomSettingsClass).

So far, I'm able to generate the ContextMenu and check the correct MenuItem, based on the setting value. I did this using a MultiBinding to compare the enum value in the DataContext of the MenuItem to the value of the settings class enum and see if their values equal. However, the binding is only one way: clicking on an unchecked MenuItem doesn't update the binding. I have a feeling I'm missing something, but this part of WPF is a bit more fuzzy to me.

Here's what I have so far:

<UserControl>
    <UserControl.Resources>
        <ObjectDataProvider MethodName="GetValues" ObjectType="{x:Type system:Enum}" x:Key="MyCustomEnumProvider">
            <ObjectDataProvider.MethodParameters>
                <x:Type Type="local:MyCustomEnum" />
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
        <local:EnumEqualsConverter x:Key="EnumEqualsConverter" />
    </FrameworkElement.Resources>
   <FrameworkElement.ContextMenu>
        <ContextMenu ItemsSource="{Binding Source={StaticResource MyCustomEnumProvider}}">
            <ContextMenu.ItemContainerStyle>
                <Style TargetType="MenuItem">
                    <Setter
                        Property="IsChecked">
                        <Setter.Value>
                            <MultiBinding Converter="{StaticResource EnumEqualsConverter}">
                                <MultiBinding.Bindings>
                                    <!--First binding source is the application setting value-->
                                    <Binding Source="{x:Static local:MyCustomSettingsClass.Default}" Path="MyCustomEnumSetting" />
                                    <!--Second binding source is the enum value in the data context of the MenuItem-->
                                    <Binding RelativeSource="{RelativeSource Self}" Path="DataContext" Mode="OneWay" />
                                </MultiBinding.Bindings>
                            </MultiBinding>
                        </Setter.Value>
                    </Setter>
                </Style>
            </ContextMenu.ItemContainerStyle>
        </ContextMenu>
    </FrameworkElement.ContextMenu>
</FrameworkElement>

And the code for my IMultiValueConverter:

public sealed class EnumEqualsConverter : IMultiValueConverter
{
    object IMultiValueConverter.Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        IEnumerable<Enum> enums = values.Cast<Enum>();
        var value1 = enums.ElementAt(0);
        var value2 = enums.ElementAt(1);
        return value1.Equals(value2);
    }

    object[] IMultiValueConverter.ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Any suggestions for a different direction I could go to get the results I'm looking for?

bozalina
  • 89
  • 1
  • 13

1 Answers1

1

You have used Multibinding to check your checkbox.. It will be one way unless you have done some magic in ConvertBack method of your MultiValueConverter. The thing that you want to achieve can be done like below:

With your MultiBinding in place, you can bind your Menuitem to a command on your VM/codebeind and send the Menuitem's DataContext in CommandParameter. In your commmand handler you can update you static property with the command parameter.

     <Style TargetType="MenuItem">
                    <Setter Property="Command" Value="{Binding MyCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"/>
                    <Setter Property="CommandParameter" Value="{Binding}"/>
      </Style>
Nitin
  • 18,344
  • 2
  • 36
  • 53
  • That does indeed solve my problem. I was really hoping to do it all through binding, but this unblocks me. Thanks for the answer. – bozalina Sep 13 '13 at 14:51