zoukankan      html  css  js  c++  java
  • WPF ContextMenu 在MVVM模式中绑定 Command及使用CommandParameter传参

    ContextMenu无论定义在.cs或.xaml文件中,都不继承父级的DataContext,所以如果要绑定父级的DataContext,直接DataContext=“{Binding}”是行不通的

    不能绑父级,但是能绑资源

    第一步:定义一个中间类用来做资源对象

     1 public class BindingProxy : Freezable
     2     {
     3         #region Overrides of Freezable
     4 
     5         protected override Freezable CreateInstanceCore()
     6         {
     7             return new BindingProxy();
     8         }
     9 
    10         #endregion
    11 
    12         public object Data
    13         {
    14             get { return (object)GetValue(DataProperty); }
    15             set { SetValue(DataProperty, value); }
    16         }
    17 
    18         public static readonly DependencyProperty DataProperty =
    19             DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
    20     }

    第二步:引用命名空间,在控件中定义资源

    1 <UserControl.Resources>
    2         <libBinding:BindingProxy x:Key="BindingProxy" Data="{Binding}"/>
    3     </UserControl.Resources>

    第三步:绑定ContextMenu、MenuItem

    (Button.Command 和 ContextMenu.IsOpen 的绑定部分可以不关注,这两个绑定是用来控制ContextMenu打开的)

     1 <Button Command="{Binding Customfold}">
     2             <Button.ContextMenu>
     3                 <ContextMenu DataContext="{Binding Data,Source={StaticResource BindingProxy}}"  
     4                              ItemsSource="{Binding ItemModelCollection}"
     5                              IsOpen="{Binding OpenCustomfold,Mode=OneWay}">
     6                     <ContextMenu.ItemContainerStyle>
     7                         <Style TargetType="MenuItem">
     8                             <Setter Property="Header" Value="{Binding ...}"/>
     9                             <Setter Property="Command" Value="{Binding ...}"/>
    10                             <Setter Property="CommandParameter" Value="{Binding ...}"/>
    11                         </Style>
    12                     </ContextMenu.ItemContainerStyle>
    13                 </ContextMenu>
    14             </Button.ContextMenu>
    15             <Image .../>
    16         </Button>

    第四步:传递参数

    ContextMenu是它自身视觉树的根节点,所以即使通过RelativeSource.FindAncestor也找不到要传递的参数。

    解决:可以通过PlacementTarget解决。微软对PlacementTarget的解释是:获取或设置UIElement,当它打开时相对于它确定ContextMenu的位置。应该可以理解为放置此ContextMenu的UIElement。

     1 CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}, Path=PlacementTarget}"  

    如果要传递Item,如ListBox的SelectedItem:

     1 CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}, Path=PlacementTarget.SelectedItem}"  

    参考:

    http://www.thomaslevesque.com/2011/03/21/wpf-how-to-bind-to-data-when-the-datacontext-is-not-inherited/

    http://stackoverflow.com/questions/1580753/wpf-contextmenu-with-itemssource-how-to-bind-to-command-in-each-item

  • 相关阅读:
    MongoDB查询
    MongoDB增删改查
    redis复制
    HTTP请求方法与状态码
    Solr工作原理
    idea多行同一列同时编辑;多光标处同时编辑方法
    SVN merge 三种方式
    vue中msgbox的使用;如何在msgbox中新增一个输入框组件传值给后台
    切换或重新输入svn用户名密码或通过tortoisesvn查看svn密码
    MyBatis中#{}和${}的区别
  • 原文地址:https://www.cnblogs.com/muran/p/6702444.html
Copyright © 2011-2022 走看看