WPF:菜单项仅绑定命令参数一次 [英] WPF: Menu Items only bind command parameters once

查看:20
本文介绍了WPF:菜单项仅绑定命令参数一次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用带有命令的菜单时,我已经注意到了几次,它们不是很动态,检查一下.我正在从一组颜色创建一个菜单,我用它来为数据网格中的列着色.无论如何,当我第一次打开菜单(它的上下文菜单)时,命令参数绑定发生并且它绑定到上下文菜单打开的列.但是,下次我提出它时,似乎 wpf 会缓存菜单,并且不会重新绑定命令参数.所以我只能在上下文菜单出现的初始列上设置颜色.

Ive noticed this a couple of times when using menus with commands, they are not very dynamic, check this out. I am creating a menu from a collection of colours, I use it to colour a column in a datagrid. Anyway when i first bring up the menu (its a context menu) the command parameter binding happens and it binds to the column that the context menu was opened on. However the next time i bring it up it seems wpf caches the menu and it doesnt rebind the command parameter. so i can set the colour only on the initial column that the context menu appeared on.

过去我通过使菜单完全动态并在菜单关闭时销毁集合并在下次打开时强制重建来解决这种情况,我不喜欢这种黑客攻击.有人有更好的方法吗?

I have got around this situation in the past by making the menu totally dynamic and destroying the collection when the menu closed and forcing a rebuild the next time it opened, i dont like this hack. anyone got a better way?

    <MenuItem
       Header="Colour"
       ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:ResultEditorGrid}}, Path=ColumnColourCollection}"
       ItemTemplate="{StaticResource colourHeader}" >
       <MenuItem.Icon>
          <Image
             Source="{StaticResource ColumnShowIcon16}" />
       </MenuItem.Icon>
       <MenuItem.ItemContainerStyle>
          <Style
             TargetType="MenuItem"
             BasedOn="{StaticResource systemMenuItemStyle}">
             <!--Warning dont change the order of the following two setters
                                otherwise the command parameter gets set after the command fires,
                                not mush use eh?-->
             <Setter
                Property="CommandParameter">
                <Setter.Value>
                   <MultiBinding>
                      <MultiBinding.Converter>
                         <local:ColumnAndColourMultiConverter/>
                      </MultiBinding.Converter>
                      <Binding RelativeSource="{RelativeSource AncestorType={x:Type DataGridColumnHeader}}" Path="Column"/>
                      <Binding Path="."/>
                   </MultiBinding>
                </Setter.Value>
             </Setter>
             <Setter
                Property="Command"
                Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:ResultEditorGrid}}, Path=ColourColumnCommand}" />
          </Style>
       </MenuItem.ItemContainerStyle>
    </MenuItem>

推荐答案

问题是 ContextMenu 的 显然是他们自己视觉的根源树 我在某处读到它的父级数据上下文,但只有一次加载,所以如果父级数据上下文更改,则菜单项不会.(不幸的是我找不到那个正确的链接)

The problem is that ContextMenu's are apparently the root of their own visual tree I read somewhere that it takes the datacontext its parent, but only once on loading, so if the parents datacontext changes the menuitems does not. (unfortunately I can't find a link for that right not)

我之前遇到过这个问题,我做的是使用 Josh Smith 的虚拟分支模式.这是相当技术性的,但这篇文章帮助我很好地理解了这个视觉树的废话是怎么回事.

I have encountered this problem before, and what I did was use Josh Smith's Virtual Branch Pattern. It's fairly technical but the article helped me understand really well what was going on with this visual tree nonsense.

本质上,您创建了绑定到视图数据上下文的桥.桥被创建为静态资源,允许您从上下文菜单绑定到它,即使它在可视化树之外.

Essentially you create this bridge that binds to the view's datacontext. The bridge is created as a static resource, allowing you to bind to it from the context menu even if it is outside the visual tree.

将此添加到您的 xaml:

Add this to your xaml:

<Window.Resources>
   <!-- This is the "root node" in the virtual branch
   attached to the logical tree. It has its
   DataContext set by the Binding applied to the
   Window's DataContext property. -->
   <FrameworkElement x:Key="DataContextBridge" />
</Window.Resources>

<Window.DataContext>
   <!-- This Binding sets the DataContext on the "root node"
   of the virtual logical tree branch.  This Binding
   must be applied to the DataContext of the element
   which is actually assigned the data context value. -->
   <Binding
    Mode="OneWayToSource"
    Path="DataContext"
    Source="{StaticResource DataContextBridge}"
   />
</Window.DataContext>

这就是我所说的桥.它获取数据上下文并将其 __pushes_ 到桥数据上下文,这是(正如我之前所说的)静态资源.

This is the bridge I spoke of. It takes the datacontext and __pushes it_ to to the bridges datacontext, which is (as I said before) a static resource.

然后您只需将其添加到上下文菜单的数据上下文中:

Then you simply this to the contextmenu's datacontext:

 DataContext="{Binding
               Source={StaticResource DataContextBridge},
               Path=DataContext}"

现在扔掉所有的相对路径等,在菜单项中使用常规绑定,你应该没问题.数据上下文将照常更新.

Now throw away all the relative pathing etc and use regular binding inside the menu items, and you should be fine. The datacontext will update as usual.

您显然必须在数据上下文中拥有一些属性才能辨别要使用哪个命令,但我相信您可以弄清楚.此解决方案仅处理上下文菜单不更新的方式

You will obviously have to have some property in the datacontext to discern which command to use, but i'm sure you can figure it out. This solution just deals with the way contextmenu's dont update

这篇关于WPF:菜单项仅绑定命令参数一次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆