I have a list box for which I am styling ItemContainer to include a context menu. Here is the xaml for the same.
Your problem lies in that you are trying to bind the target to an element which doesn't exist in the same visual tree e.g. you have a ContextMenu
on which the item resides.
To correctly get an action target, you need to use the ContextMenu
s PlacementTarget
property.
Check out the following answer on SO for the XAML
WPF Context Menus in Caliburn Micro
So the following XAML should work:
<MenuItem Header="Blah" cal:Message.Attach="SomeMethod()" cal:Action.TargetWithoutContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}">
This should look for the PlacementTarget
on the ContextMenu
and set the target for the action to the value of PlacementTarget.Tag
(which should be the ListBoxItem
).
If you set ListBoxItem.Tag
(as you have already done) to be the DataContext
of the parent container (the ListBox
) you should be ok
so the tag binding should be:
<Setter Property="Tag" Value="{Binding Path=DataContext, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBox}}"/>
e.g. the whole thing should be:
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Tag" Value="{Binding Path=DataContext, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBox}}"/>
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu cal:Action.TargetWithoutContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}">
<MenuItem Header="Remove Group" cal:Message.Attach="DeleteGroup()" />
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
Adding to Charleh's answer, if you're going to be using the same data context as the control, then you can just bind the DataContext
instead of a Tag
. Makes it a bit cleaner too.
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu cal:Action.TargetWithoutContext="{Binding Path=PlacementTarget.DataContext, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}" >
<MenuItem Header="Remove Group"
cal:Message.Attach="DeleteGroup()" />
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>