Reputation: 790
I'm working on a WPF project using Caliburn Micro as a framework for MVVM, and during the last week I've been lucky enough to find every solution to any problem on StackOverflow, but now I'm facing a bigger issue that I can't solve by myself.
I have a View containing a TreeView; each item of the treeview should invoke a method when:
This is the TreeView:
<TreeView x:Name="projectTreeView"
Visibility="{Binding ExplorerVisibility, Converter={StaticResource visibilityConverter}}">
<TreeViewItem Header="{Binding ProjectName}" IsExpanded="True">
<TreeViewItem Header="Category 1"/>
<TreeViewItem Header="Category 2" ItemsSource="{Binding Images}">
<TreeViewItem.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem Header="Remove"
cal:Action.TargetWithoutContext="{Binding Path=DataContext, ElementName=projectTreeView}"
cal:Message.Attach="[Event Click] = [Action RemoveResource()]"/>
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</TreeViewItem.ItemContainerStyle>
<TreeViewItem.ItemTemplate>
<HierarchicalDataTemplate>
<HierarchicalDataTemplate.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Setter Property="IsExpanded" Value="True" />
<Style.Triggers>
<EventTrigger RoutedEvent="Collapsed">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames
Duration="0"
Storyboard.TargetProperty="(TreeViewItem.IsExpanded)">
<DiscreteBooleanKeyFrame KeyTime="0" Value="True" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
</HierarchicalDataTemplate.ItemContainerStyle>
<ContentControl cal:Action.TargetWithoutContext="{Binding Path=DataContext, ElementName=projectTreeView}"
cal:Message.Attach="[Event MouseDoubleClick] = [Action OpenResource(projectTreeView.SelectedItem)]">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding ResourceName}" Margin="5,0,0,0"/>
</StackPanel>
</ContentControl>
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</TreeViewItem.ItemTemplate>
</TreeViewItem>
</TreeViewItem>
</TreeView>
The attached ViewModel contains both methods:
public class MyViewModel
{
...
public void OpenResource(object obj) { ... }
public void RemoveResource() { ... }
}
For some reason OpenResource works perfectly, while when I click on the context menu item (after right click) the application crashes with the exception:
An unhandled exception of type 'System.Exception' occurred in WindowsBase.dll
Additional information: No target found for method RemoveResource.
I found something related to the same problem here on the forum and on the support forum, but I was not able to fix the problem with those tips.
Do you have any idea about what's going on in my TreeView?
Thank you very much for the help!
Upvotes: 1
Views: 1499
Reputation: 169190
The ContextMenu
resides in its own visual tree and can't bind to the TreeView
using an ElementName
.
You could try to bind the Tag
property of the TreeViewItem
to the parent TreeView
and then bind to it using the PlacementTarget
property of the ContextMenu
:
<Style TargetType="TreeViewItem">
<Setter Property="Tag" Value="{Binding RelativeSource={RelativeSource AncestorType=TreeView}}" />
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem Header="Remove"
cal:Action.TargetWithoutContext="{Binding Path=PlacementTarget.Tag.DataContext, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}"
cal:Message.Attach="[Event Click] = [Action RemoveResource()]"/>
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
Upvotes: 3