上下文菜单绑定永远不会被执行

本文关键字:执行 永远 菜单 绑定 上下文 | 更新日期: 2023-09-27 18:17:06

我有ListView控件在我的视图与它自己的视图模型a .我做了一个单独的UserControl作为ListViewItem使用,因为它的样式需要很多空间。在这个ListViewItem我有一个按钮,它被绑定到视图模型a,它工作得很好。

由于上下文菜单有自己的可视化树,不能通过祖先绑定,我使用绑定代理来解决这个问题。我稍微调整了一下,所以它适用于我的特殊情况,因为如果它只是使用{Binding},它会绑定到item的模型,而不是listview的viewmodel。

<helpers:BindingProxy x:Key="proxy" Data="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListView}}"/>

为了检查绑定是否正确,我使用了一个转换器作为一种方法,只是有一个断点来检查源。一切都很好,我在那里得到了我的视图模型。

现在,当我尝试在上下文菜单中绑定这个

<UserControl.ContextMenu>
    <ContextMenu>
        <MenuItem Header="Open"
                  Command="{Binding DataContext.OpenChatCommand, Source={StaticResource proxy}, Converter={StaticResource DataBindingDebugConverter}}"
                  CommandParameter="{Binding}"/>
   </ContextMenu>
</UserControl.ContextMenu>

命令永远不会被调用。我添加了转换器来查看是否有问题,但结果是,我从来没有用到转换器,这反过来意味着这段代码永远不会执行。

任何有任何想法的人,为什么会发生这种情况,以及如何解决这个问题,欢迎。

我认为这是编译器故障

上下文菜单绑定永远不会被执行

我只是简单地读了一下那个" binding proxy ";你提到的,但据我所知,DataGridTextColumn和它的DataGrid在同一个可视化树中,只是它的DataContext被绑定到它的数据上。

对于ContextMenu,则完全不同。这棵树和它的父树是分开的。在资源中使用代理对象是没有意义的,因为它来自不同的可视树。当您使用StaticResource时,WPF将在这些元素的Resource属性(这是一个ResourceDictionary)中逐级向上搜索它的可视化树。

一种方法是将代理变成单例,并使用Source={x:Static helpers:BindingProxy.Instance}。当然,这样做意味着你的代理只能被一个视图使用,否则会发生意想不到的事情。

另一种方法是利用ContextMenuPlacementTarget属性。

<ContextMenu DataContext="{Binding Path=PlacementTarget.DataContext,
             RelativeSource={RelativeSource Self}}">

这是首选的方式,但您需要确保父节点的DataContext确实是您需要的VM。

编辑

没有超级优雅的MVVM方式。最好的方法可能是使用Tag属性。

<ContextMenu DataContext="{Binding Path=PlacementTarget.Tag,
             RelativeSource={RelativeSource Self}}">

列表视图控件:

<MyControl:MyListViewItem .... Tag="{Binding Path=DataContext, RelativeSource={RelativeSource AncestorType={x:Type MyControl:MyListViewView}}}"}" ...>