1

I can`t seem to get this right click popup menu to work.

<TreeView Name="NavigationPanel" ItemsSource="{Binding NavigationList}" />
<Style TargetType="{x:Type TreeViewItem}" >
    <Setter Property="ContextMenu">
        <Setter.Value>
            <ContextMenu  DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TreeView}}, Path=DataContext}">
                <MenuItem Header="Delete" Command="{Binding Path=CommandPopupClick}" CommandParameter="{Binding Path=SelectedItem}"/>
                <Separator />
                <MenuItem Header="Properties" Command="{Binding Path=CommandPopupClick}" CommandParameter="{Binding Path=SelectedItem}"/>
            </ContextMenu>
        </Setter.Value>
    </Setter>
</Style>
//Delegated command
public DelegateCommand CommandPopupClick { get; set; } 

//Assigning the delegate command.
CommandPopupClick = new DelegateCommand(PopupClick, CanMyCommand);

//Event for rightclick option clicked
public void PopupClick(Object Parameters)
{
    var something = Parameters; //Break is here to see if the event fires
}

I can see the popup menu with the items 'Delete' and 'Properties' in it. However, when I click either one of them it doesn't fire the event.

NOTE: the delegate command system works for everything else, I don't think that's the issue.

I really do not want to use Name.Click += new RoutedEvent() if I can help it.

Thanks.

Errors in Debug as requested

A first chance exception of type 'System.IO.FileNotFoundException' occurred in mscorlib.dll
A first chance exception of type 'System.IO.FileNotFoundException' occurred in mscorlib.dll
'Enterprise.exe' (CLR v4.0.30319: Enterprise.exe): Loaded 'Microsoft.GeneratedCode'. 
'Enterprise.exe' (CLR v4.0.30319: Enterprise.exe): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\PresentationFramework-SystemCore\v4.0_4.0.0.0__b77a5c561934e089\PresentationFramework-SystemCore.dll'. Cannot find or open the PDB file.
A first chance exception of type 'System.IO.IOException' occurred in PresentationFramework.dll
A first chance exception of type 'System.IO.IOException' occurred in PresentationCore.dll
'Enterprise.exe' (CLR v4.0.30319: Enterprise.exe): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\UIAutomationTypes\v4.0_4.0.0.0__31bf3856ad364e35\UIAutomationTypes.dll'. Cannot find or open the PDB file.
The thread 0x1954 has exited with code 259 (0x103).

Resolution:

    <Setter Property="ContextMenu">
        <Setter.Value>
            <ContextMenu DataContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
                <MenuItem Header="Delete" 
                          Command="{Binding CommandPopupClick}" 
                          CommandParameter="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource  AncestorType=ContextMenu}}" 
                          CommandTarget="{Binding PlacementTarget, RelativeSource={RelativeSource Self}}" />
            </ContextMenu>
        </Setter.Value>
    </Setter>
</Style>

<TreeView Name="NavigationPanel" ItemsSource="{Binding NavigationList}" Tag="{Binding Path=DataContext, ElementName=Main}"/>

Thank you for all who assisted.

New Bee
  • 991
  • 1
  • 13
  • 24

3 Answers3

2

You can't use a RelativeSource Binding to access the TreeView.DataContext from the ContextMenu because it is not in the main UI visual tree. This is a very well documented problem and the solution is to pass the DataContext object through to the ContextMenu using the ContextMeny.PlacementTarget property and the Tag property on the object that has the Contextmenu applied to it.

Having already written and re-written about this many times, nowadays, I much prefer to request that you read my answers to the ContextMenu.PlacementTarget is not getting set, no idea why and Add context menu in datagrid, how to get the select Item value questions here on Stack Overflow for full explanations and code examples. If you need further help, just search the internet for 'WPF ContextMenu DataContext' or something similar and you should find dozens of tutorials on this exact topic.

Community
  • 1
  • 1
Sheridan
  • 68,826
  • 24
  • 143
  • 183
1

ContextMenu ist not part the the Visual Tree and so FindAncestory data binding won't work.

You could set the DataContexton the ContextMenuexplicitly though.

e.g. you could create an instance of your ViewModel / DataContext directly in XAML if that's an option.

<Style TargetType="{x:Type TreeViewItem}">
  <Setter Property="ContextMenu">
    <Setter.Value>
      <ContextMenu>
        <ContextMenu.DataContext>
          <local:MyViewModel/>
        </ContextMenu.DataContext>

        <MenuItem Command="{Binding Path=CommandPopupClick}"
                  CommandParameter="{Binding Path=SelectedItem}"
                  Header="Delete" />
        <Separator />
        <MenuItem Command="{Binding Path=CommandPopupClick}"
                  CommandParameter="{Binding Path=SelectedItem}"
                  Header="Properties" />
      </ContextMenu>
    </Setter.Value>
  </Setter>
</Style>

Or get it from a StaticResource.

  <Window.Resources>
    <local:MyViewModel x:Key="ctx"/>

    <Style TargetType="{x:Type TreeViewItem}">
      <Setter Property="ContextMenu">
        <Setter.Value>
          <ContextMenu DataContext="{StaticResource ctx}">

            <MenuItem Command="{Binding Path=CommandPopupClick}"
                      CommandParameter="{Binding Path=SelectedItem}"
                      Header="Delete" />
            ....

          </ContextMenu>
        </Setter.Value>
      </Setter>
    </Style>
  </Window.Resources>
Wolfgang Ziegler
  • 1,675
  • 11
  • 23
0

Since learning more and more about C# and WPF if anyone else is looking for an answer regarding this. the answer is simple.

Your going about it the wrong way. If you need to use a "Behaviour" over and over again and your using either a MVVM style code (or you think you are because its probably not quite there yet) You need to use what they call an Attached Property.

Simply Put.

  1. Create an attached property class. http://dotnetbyexample.blogspot.com.au/2010/05/attached-dependency-properties-for.html should get you started
  2. Create a template to your Menu Items Example Below
  3. Create Standard Menu Items.
  4. Handle Everything in your Attached Property PropertyMetadata Event Handler.

     <Style TargetType="MenuItem">
          <Setter Property="Properties:ControlMenuItem.InvokeClick" Value="{Binding  RelativeSource={RelativeSource Self}}"/>
     </Style>
    
New Bee
  • 991
  • 1
  • 13
  • 24