<ContextMenu x:Key="ModeMenu">            <MenuItem Header="添加" Command="{Binding AddCommand}"                      CommandParameter="{Binding ElementName=ModesTree, Path=SelectedItem}">                <MenuItem.Icon>                    <Image Source="../Images/Add.png" Width="16" Height="16" />                </MenuItem.Icon>            </MenuItem>        </ContextMenu>

<HierarchicalDataTemplate x:Key="ModeTemplate" DataType="{x:Type Model:ModeInfo}" ItemsSource="{Binding Path=PlanInfoList}" >             <StackPanel Orientation="Horizontal" ContextMenu="{StaticResource ModeMenu}"                         DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}">                <Image x:Name="imgStatus" Source="../Images/Add.png" Width="16" Height="16" />                <TextBlock Margin="2,0,0,0" VerticalAlignment="Center" FontWeight="Bold" Text="{Binding ModeName}"  />            </StackPanel>        </HierarchicalDataTemplate>

如代码所示,这个MenuItem的Command并不起作用。网上有人给出的解释是:ContentMenu是作为你一个popup的窗口出现在UI上的,因此,这个Popup和原来的窗口并不是同一个VisualTree,既然不在同一个VisualTree中,则无法找到DataContext。

解决方法如下:

定义一个类CommandReference:

public class CommandReference : Freezable, ICommand, ICommandSource    {public CommandReference()        {

        }

public static readonly DependencyProperty CommandParameterProperty =          DependencyProperty.Register("CommandParameter",typeof(object),typeof(CommandReference),new PropertyMetadata((object)null));

public object CommandParameter        {get            {return (object)GetValue(CommandParameterProperty);            }set            {                SetValue(CommandParameterProperty, value);            }        }

public static readonly DependencyProperty CommandTargetProperty =           DependencyProperty.Register("CommandTarget",typeof(IInputElement),typeof(CommandReference),new PropertyMetadata((IInputElement)null));

public IInputElement CommandTarget        {get            {return (IInputElement)GetValue(CommandTargetProperty);            }set            {                SetValue(CommandTargetProperty, value);            }        } 

public static readonly DependencyProperty CommandProperty = DependencyProperty.Register("Command", typeof(ICommand), typeof(CommandReference), new PropertyMetadata(new PropertyChangedCallback(OnCommandChanged)));

public ICommand Command        {get { return (ICommand)GetValue(CommandProperty); }set { SetValue(CommandProperty, value); }        }

#region ICommand Members

public bool CanExecute(object parameter)        {if (Command != null)return Command.CanExecute(CommandParameter);return false;        }

public void Execute(object parameter)        {            Command.Execute(CommandParameter);        }

public event EventHandler CanExecuteChanged;

private static void OnCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)        {            CommandReference commandReference = d as CommandReference;            ICommand oldCommand = e.OldValue as ICommand;            ICommand newCommand = e.NewValue as ICommand;

if (oldCommand != null)            {                oldCommand.CanExecuteChanged -= commandReference.CanExecuteChanged;            }if (newCommand != null)            {                newCommand.CanExecuteChanged += commandReference.CanExecuteChanged;            }        }

#endregion

#region Freezable

protected override Freezable CreateInstanceCore()        {throw new NotImplementedException();        }

#endregion    }

然后修改View中的代码,先插入一个CommandReference资源,将其绑定到命令,再将菜单的命令绑定到资源,如下所示:

<UserControl.Resources><c:CommandReference x:Key="AddModeCommandRef" Command="{Binding Path=AddModeCommand}"/><ContextMenu x:Key="RootMenu" >            <MenuItem Header="添加" Command="{StaticResource AddModeCommandRef}" >                                <MenuItem.Icon>                    <Image Source="../Images/Add.png" Width="16" Height="16" />                </MenuItem.Icon>            </MenuItem>        </ContextMenu><HierarchicalDataTemplate x:Key="ModeTemplate" DataType="{x:Type Model:ModeInfo}" ItemsSource="{Binding Path=PlanInfoList}" >            <StackPanel Orientation="Horizontal" ContextMenu="{StaticResource ModeMenu}" DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}">                 <Image x:Name="imgStatus" Source="../Images/Add.png" Width="16" Height="16" />                <TextBlock Margin="2,0,0,0" VerticalAlignment="Center" FontWeight="Bold" Text="{Binding ModeName}" />            </StackPanel>        </HierarchicalDataTemplate>

最后在ViewModel中定义命令即可:

public ICommand AddModeCommand { get; set; }

参考文章:

http://social.msdn.microsoft.com/Forums/zh-SG/wpfzhchs/thread/13bcc6e4-d3f7-40c8-a9e8-ee35918edc14

http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/36ce07fc-64de-4dc9-8012-3c4f03605c30/

转载于:https://www.cnblogs.com/wenjingu/archive/2011/11/14/2248278.html

HierarchicalDataTemplate中的ContextMenu的Command绑定相关推荐

  1. MVVM 下 ContextMenu的命令绑定

    原文:MVVM 下 ContextMenu的命令绑定 由于ContextMenu不继承父级的DataContext,所以如果要绑定父级的DataContext,直接DataContext=" ...

  2. WPF中的命令与命令绑定(二)

    WPF中的命令与命令绑定(二)                                              周银辉 在WPF中,命令(Commanding)被分割成了四个部分,分别是IC ...

  3. Python中TKinter的输入框如何绑定回车键事件调用功能函数

    Python中TKinter的输入框如何绑定回车键事件调用功能函数 TKinter中的Entry输入框,与普通的按钮类型有所不同,没有command的属性来直接调用一个函数功能,所以,如果要通过键盘按 ...

  4. WPF关于Command绑定

    发现一位大佬写的Command绑定写法,代码量少,在此记录下,上代码! 首先建立 DelegateCommand.cs public class DelegateCommand : ICommand{ ...

  5. WPF_MVVM实现Command绑定获取事件参数EventArgs

    这里主要实现的效果是窗体在关闭的时候,需要弹出消息框确认是否关闭,来拦截窗体的Closing事件,无需通过Loaded事件传递控件对象到ViewModel中. 1.创建WPF项目,需要引入System ...

  6. 华为交换机ssh思科交换机_思科交换机交换机中ip、mac地址绑定

    在思科交换机中为了防止ip被盗用或员工乱改ip,可以做以下措施,既ip与mac地址的绑定,和ip与交换机端口的绑定. 一.通过IP查端口 先查MAC地址,再根据MAC地址查端口: bangonglou ...

  7. 学习C#中调用COM,后期绑定(以及对WinHttp COM对象的C#封装)

    学习C#中调用COM,后期绑定(以及对WinHttp COM对象的C#封装) 学习C#中调用COM,后期绑定全部代码 开始学习C#了,没打算从语法一点一点的看起!所以上来就直接开始代码了!同时也和De ...

  8. cisco 2960 VLAN MAC_思科交换机交换机中ip、mac地址绑定

    在思科交换机中为了防止ip被盗用或员工乱改ip,可以做以下措施,既ip与mac地址的绑定,和ip与交换机端口的绑定. 一.通过IP查端口 先查MAC地址,再根据MAC地址查端口: bangonglou ...

  9. 【Groovy】Groovy 脚本调用 ( Groovy 脚本中的作用域 | 本地作用域 | 绑定作用域 )

    文章目录 一.Groovy 脚本中的作用域 ( 本地作用域 | 绑定作用域 ) 二.Groovy 脚本中的作用域代码示例 一.Groovy 脚本中的作用域 ( 本地作用域 | 绑定作用域 ) 在 Gr ...

最新文章

  1. C#保存图片到特定目录
  2. 98%的人没解出的德国面试逻辑题(离散数学篇)!?
  3. IDC dump 内存
  4. UI组件之AdapterView及其子类(六)ExpandableListView组件和ExpandableListActivity的使用
  5. 【GDKOI2003】分球
  6. 将两大小完全相同的照片进行加权混合对比
  7. 生成六位验证码python代码
  8. 提高程序员职场价值的10大技巧
  9. jdbc操作mysql延时操作_关于jdbc通过Statement和PrepareStatement进行数据库批处理操作,以提供程序效率...
  10. UI设计实用临摹素材|APP设计的信息可视化!
  11. Python读取安卓手机GPS信息
  12. 基于SSM的作业调度平台-java作业调度平台
  13. java程序知识_java的基本知识点
  14. 【数据仓库】 BI 项目管理之角色和职责
  15. BIGEMAP如何下载高程卫星地图
  16. Axis2+Rampart(WSS4J)实现UsernameToken认证方式的WS-Security(基于SOAP的Web安全调用机制)
  17. 关于阿里巴巴icon矢量图显示空白问题
  18. matlab求解积分总结
  19. 【无标题】三星Xpress M2020打印机刷免芯片
  20. 云服务器BBC销售渠道,云服务器bbc

热门文章

  1. ip subnet-zero 和ip classless 的用法
  2. h3c服务器系统关闭pxe,h3c服务器设置pxe启动
  3. PostgreSQL13逻辑备份pg_dump
  4. 服务器2003系统黑屏怎么办,windows-server-2003 – Windows Server 2003 – 黑屏,光标在启动时...
  5. 串口接收数据转换成double型
  6. windows c++ 原子操作_高分辨质谱数据处理操作篇
  7. 算法训练 纪念品分组(java)
  8. 鸿蒙os在3月底推送,华为鸿蒙OS Beta 3将从3月31日起推送
  9. loot recycler_loot++ - MC百科搜索 - MC百科|最大的Minecraft中文MOD百科
  10. tomcat给android发图片,一步一步学会http获取tomcat服务端的图片,在android客户端显示...