"No target found for method" thrown by Caliburn Message.Attach()
c#, caliburn.micro, wpf, wpf-4.0
Solution
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>
Problem
I have a list box for which I am styling ItemContainer to include a context menu. Here is the xaml for the same. ``` <ListBox.ItemContainerStyle> <Style TargetType="{x:Type ListBoxItem}"> ... <Setter Property="ContextMenu"> <Setter.Value> <ContextMenu> <MenuItem Header="Remove Group" cal:Message.Attach="DeleteGroup"/> </ContextMenu> </Setter.Value> </Setter> </Style> ``` I have coded the target method in ViewModel as given below. ``` public void DeleteGroup() { //ToDo ... } ``` The ViewModel is set as the DataContext of the UserControl in which there is the ListBox. The above code results in "no target found for method". I am not sure why this doesn't work. I have also tried the following variation ``` <MenuItem Header="Remove Group" cal:Message.Attach="DeleteGroup" cal:Action.Target="{Binding ElementName=UCRelayDispositionView, Path=DataContext}"> ``` where UCRelayDispositionView is the name of the UserControl. Why does the above code do not work? Edit: 1 Also tried the following ``` <MenuItem Header="Remove Group" cal:Message.Attach="DeleteGroup" cal:Action.TargetWithoutContext="{Binding ElementName=UCRelayDispositionView, Path=DataContext}"> ``` and this ``` <MenuItem Header="Remove Group" cal:Message.Attach="DeleteGroup" cal:Action.TargetWithoutContext="{Binding ElementName=UCRelayDispositionView}"> ``` EDIT: 2 I have tried to use the Tag in the following way on ItemContainer but it doesn't work either. ``` <ListBox.ItemContainerStyle> <Style TargetType="{x:Type ListBoxItem}"> <Setter Property="Tag" Value="{Binding Path=DataContext, ElementName=UCRelayDispositionView}"/> <Setter Property="ContextMenu"> <Setter.Value> <ContextMenu> <MenuItem Header="Remove Group" cal:Message.Attach="DeleteGroup()" cal:Action.TargetWithoutContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}"/> </ContextMenu> </Setter.Value> </Style> </ListBox.ItemContainerStyle> ``` EDIT 3: Binding Errors ``` System.Windows.Data Error: 40 : BindingExpression path error: 'PlacementTarget' property not found on 'object' ''MenuItem' (Name='')'. BindingExpression:Path=PlacementTarget.Tag; DataItem='MenuItem' (Name=''); target element is 'MenuItem' (Name=''); target property is 'TargetWithoutContext' (type 'Object') System.Windows.Data Error: 4 : Cannot find source for binding with reference 'ElementName=UCRelayDispositionView'. BindingExpression:Path=DataContext; DataItem=null; target element is 'ContextMenu' (Name=''); target property is 'Tag' (type 'Object') ```