Question

I have a property "Mode" on my view model. Whenever this property changes, I want to see if it is equal to any menu item header in my context menu. If it is equal, I want the IsChecked property of that menu item to be set to true. How can this be accomplished?

I tried to set the value with the following line:

({Binding RelativeSource={RelativeSource Self}, Path=Header})

but you cannot use binding for the value. Here is the rest of my attempt with the value left blank currently:

<ContextMenu>
    <ContextMenu.ItemContainerStyle>
       <Style TargetType="{x:Type MenuItem}">
           <Setter Property="IsChecked" Value="False" />
           <Style.Triggers>
                <DataTrigger Binding="{Binding Mode}" Value="???">
                     <Setter Property="IsChecked" Value="True"></Setter>
                </DataTrigger>
            </Style.Triggers>
       </Style>
    </ContextMenu.ItemContainerStyle>
    <MenuItem Header="{x:Static Name:ContextMenuStartNames.1}"/>
    <MenuItem Header="{x:Static Name:ContextMenuStartNames.1}"/>
    <MenuItem Header="{x:Static Name:ContextMenuStartNames.3}"/>
</ContextMenu>
Was it helpful?

Solution

You can use a MultiValueConverter.

public class ModeMultiConverter:IMultiValueConverter 
{
    #region Implementation of IMultiValueConverter

    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (values.Length != 2 || values[0] == null || values[1] == null)
            return Binding.DoNothing;

        var mode = values[0].ToString();
        var header = values[1].ToString();
        return mode == header;
    }

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

    #endregion
}

And in Xaml:

<MenuItem.IsChecked>
    <MultiBinding Converter="{StaticResource ModeMultiConverter}" Mode="OneWay">
        <Binding Path="PlacementTarget.DataContext.Mode" RelativeSource="{RelativeSource AncestorType=ContextMenu}"/>
        <Binding Path="Header" RelativeSource="{RelativeSource Self}"/>
    </MultiBinding>
</MenuItem.IsChecked>

You can remove the code in ItemContainerStyle.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top