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?