Pregunta

I am generating a MenuItem according the values of an enumeration and I would like to update a property with the content of the clicked menu item.

This works perfectly with a ComboBox :

enter image description here

<ComboBox ItemsSource="{Binding Source={StaticResource TimelineUnitValues}}" SelectedItem="{Binding TimelineUnit}" />

But with a MenuItem that seems an impossible mission since it doesn't have a SelectedItem property.

Generating the menu works fine but updating it with a behavior does not do anything, even though the behavior do receive the value it just doesn't update the target property.

enter image description here

<ContextMenu ItemsSource="{Binding Source={StaticResource TimelineUnitValues}}">
    <ContextMenu.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding}">
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="MouseLeftButtonDown">
                        <ei:ChangePropertyAction Changed="Freezable_OnChanged"
                                                    PropertyName="TimelineUnit"
                                                    TargetName="UserControl1"
                                                    Value="{Binding Path=.,
                                                                    Mode=OneWayToSource}" />
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </TextBlock>
        </DataTemplate>
    </ContextMenu.ItemTemplate>
</ContextMenu>

Actually I can't think of any other mechanism than using ChangePropertyAction.

(I am looking for a XAML-only solution)

Do you know how I can achieve this ?

¿Fue útil?

Solución

You said you are looking for XAML-only solution, but this involves only tiny bit of code.

First, drop your ItemTemplate and use Style instead:

<ContextMenu.ItemContainerStyle>
    <Style TargetType="MenuItem">
        <Setter Property="Command" Value="{Binding DataContext.MyCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"/>
        <Setter Property="CommandParameter" Value="{Binding}"/>
    </Style>
</ContextMenu.ItemContainerStyle>

Then add simple command in VM:

this.MyCommand = new DelegateCommand<MyEnum>(val => TimelineUnit = val);

I tested it with DevExpress DelegateCommand, but similar implementations of ICommand should work as well.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top