在上下文菜单中不调用DelegateCommand

时间:2014-06-06 07:24:42

标签: c# wpf xaml contextmenu

我似乎不能让这个右键单击弹出菜单起作用。

<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
}

我可以看到弹出式菜单中包含“删除”和“属性”项。但是,当我点击其中任何一个时,它都不会触发事件。

注意:委托命令系统适用于其他所有事情,我认为这不是问题。

如果我能提供帮助,我真的不想使用Name.Click += new RoutedEvent()

感谢。

按要求调试中的错误

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).

分辨率:                       

    <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}"/>

感谢所有协助的人。

3 个答案:

答案 0 :(得分:2)

您无法使用RelativeSource Binding访问TreeView.DataContext中的ContextMenu,因为它在主UI可视树中。这是一个记录完备的问题,解决方案是使用DataContext属性和ContextMenu属性将ContextMeny.PlacementTarget对象传递给TagContextmenu适用于此。

已经多次撰写和重写这篇文章,如今,我更愿意请求您在Stack Overflow上阅读我对ContextMenu.PlacementTarget is not getting set, no idea whyAdd context menu in datagrid, how to get the select Item value个问题的答案,以获取完整的解释和代码例子。如果您需要进一步的帮助,只需在互联网上搜索&#39; WPF ContextMenu DataContext &#39;或类似的东西,你应该找到关于这个确切主题的几十个教程。

答案 1 :(得分:1)

ContextMenu不属于Visual Tree,因此FindAncestory数据绑定不起作用。

您可以明确地在DataContext上设置ContextMenu

e.g。你可以直接在XAML中创建一个ViewModel / DataContext的实例,如果这是一个选项。

<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>

或者从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>

答案 2 :(得分:0)

因为越来越多地了解C#和WPF,如果其他人正在寻找有关此问题的答案。 答案很简单。

你走错了方向。 如果你需要使用&#34;行为&#34;一遍又一遍,你使用MVVM样式代码(或者你认为你是因为它可能还没有完全存在) 你需要使用他们所谓的附属财产。

简单地说。

  1. 创建附加属性类。 http://dotnetbyexample.blogspot.com.au/2010/05/attached-dependency-properties-for.html应该让你开始
  2. 为您的菜单项示例创建模板
  3. 创建标准菜单项。
  4. 处理附加属性PropertyMetadata事件处理程序中的所有内容。

     <Style TargetType="MenuItem">
          <Setter Property="Properties:ControlMenuItem.InvokeClick" Value="{Binding  RelativeSource={RelativeSource Self}}"/>
     </Style>