WPF ContextMenu reference an action in ViewModel

Topics: Actions & Coroutines, Framework Services, Getting Started, UI Architecture
Nov 25, 2013 at 2:50 AM
Hi,
I am trying to get a ContextMenu action on a TreeView level 3 node to work, and am
having trouble hooking up the ContextMenu action to the ViewModel and get "No target found for method ContextMenuOpened" error.

The XAML looks like this:
<HierarchicalDataTemplate x:Key="FeatureTemplate">
    <Grid HorizontalAlignment="Stretch">
    <TextBlock Text="{Binding Name}" Tag="{Binding DataContext, RelativeSource={RelativeSource Self}}">
        <telerik:RadContextMenu.ContextMenu >
        <telerik:RadContextMenu cal:Action.TargetWithoutContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}"
         cal:Message.Attach="[Event Opened] = [Action ContextMenuOpened($source)]">               
        <telerik:RadMenuItem Header="Export" cal:Message.Attach="[Event Click]=[Action ContextMenuClick($source)]"/>
        </telerik:RadContextMenu>
        </telerik:RadContextMenu.ContextMenu>
    </TextBlock>
    </Grid>
</HierarchicalDataTemplate>

<HierarchicalDataTemplate 
    x:Key="FormTemplate" 
    ItemTemplate="{StaticResource FeatureTemplate}" 
    ItemsSource="{Binding List}">
    <Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Image Source="{Binding Image}" Width="32" Height="32" HorizontalAlignment="Right" Margin="0,3"/>
    <TextBlock Grid.Column="1" Text="{Binding Name}" VerticalAlignment="Center" Margin="5"/>
    </Grid>
</HierarchicalDataTemplate>

<HierarchicalDataTemplate  
    x:Key="JobTemplate"  
    ItemTemplate="{StaticResource FormTemplate}" 
    ItemsSource="{Binding List}">
    <TextBlock Text="{Binding Name}"/>
</HierarchicalDataTemplate>

<telerik:RadTreeView Name="TreeView1" 
     Grid.Row="2" 
     cal:Message.Attach="[Event SelectionChanged] = [Action SetSelectedItem($this.SelectedItem)]" 
     Background="White" 
     ItemsSource="{Binding AvailableData}" 
     ItemTemplate="{StaticResource JobTemplate}" 
     telerik:AnimationManager.IsAnimationEnabled="False" >
</telerik:RadTreeView>
ViewModel Code:
public void ContextMenuOpened(FrameworkElement source)
{
}
Any help or suggestions would be much appreciated.
Thanks
Nov 25, 2013 at 11:50 AM
What kind of delegate does the Telerik RadContextMenu.Opened event use? If I remember correctly, only EventHandler/EventHandler<TArgs> can be used with EventTriggers (which is what CM uses for actions).
Nov 25, 2013 at 6:24 PM
Edited Nov 25, 2013 at 6:28 PM
It seems (from other posts with similar problems) that I am trying to bind the target to an element which doesn't exist in the same visual tree and that one has to set the Tag of the parent of the ContextMenu to reference the ViewModel, but that is what I am trying above and can't get to work.

If I handle it in the View, it works perfectly using the example code:

XAML:
<telerik:RadContextMenu Opened="RadContextMenu_Opened">
View:
this.radTreeView.AddHandler( RadMenuItem.ClickEvent, new RoutedEventHandler( OnContextMenuClick ) );

private void RadContextMenu_Opened(object sender, RoutedEventArgs e)
{
}

private void OnContextMenuClick(object sender, RoutedEventArgs args)
{
}
But I would like to set it up directly in the XAML, so that the ViewModel method is called directly without having to go via the View.
If I handle it in the View, I have to set up a reference to the ViewModel and then call the ViewModel's method from the View which I would like to avoid by setting it up correctly in the XAML.
Nov 25, 2013 at 7:19 PM
Check the delegate type of the event. As I said, if it is not an EventHandler, that could be the cause. The EventTrigger in interactivity does not handle other kind of delegates.