【问题标题】:WPF binding command to ContextMenuWPF 绑定命令到 ContextMenu
【发布时间】:2014-08-08 14:18:54
【问题描述】:

我遇到了 WPF 中的命令绑定问题。我有以下 xaml:

<ItemsControl ItemsSource="{Binding Entity}" Name="Lst">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <StackPanel>                    
                <Button  Content="qwerty" Command="{Binding ElementName=Lst, Path=DataContext.SaveCommand}" >
                    <Button.ContextMenu>
                        <ContextMenu>                                
                            <MenuItem Header="Send2" Command="{Binding ElementName=Lst, Path=DataContext.SaveCommand}" />
                        </ContextMenu>
                    </Button.ContextMenu>    
                </Button>
            </StackPanel>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

如您所见,Button 及其 ContextMenu 具有相似的命令绑定。但是当我单击按钮时,它的命令正在触发,当我单击上下文菜单的项目时,它的命令没有触发。我哪里错了?提前致谢!

【问题讨论】:

标签: c# wpf xaml data-binding


【解决方案1】:

我之前遇到过类似的问题,通过容器的标签属性传递数据上下文来解决它,如下所示。我让它在网格 ContextMenu 上工作,但看不出有什么理由不能在按钮上工作。如果您有任何问题,请告诉我

<Button  Content="qwerty" Tag="{Binding DataContext,ElementName=Lst}" Command="{Binding ElementName=Lst, Path=DataContext.SaveCommand}"  >
                    <Button.ContextMenu>
                        <ContextMenu DataContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">                                
                            <MenuItem Header="Send2" Command="{Binding SaveCommand}" />
                        </ContextMenu>
                    </Button.ContextMenu>    
                </Button>

【讨论】:

    【解决方案2】:

    ContextMenu 与可视化树分开,您不能与它之外的元素绑定。

    如果你检查你的输出窗口,你应该有一条消息说它找不到对象“Lst”

    一种常见且简单的解决方法是在代码隐藏中手动设置 DataContext(注意:这根本不会破坏 MVVM。您只是执行将 DataContexts 链接在一起的纯 UI 操作):

    在您的 Xaml 中:

    <Button.ContextMenu>
                            <ContextMenu Opened="OnContextMenuOpened">                                
                                <MenuItem Header="Send2" Command="{Binding ElementName=Lst, Path=DataContext.SaveCommand}" />
                            </ContextMenu>
                        </Button.ContextMenu>
    

    在代码隐藏中:

    public void OnContextMenuOpened(object sender, RoutedEventArgs args)
    {
        (sender as ContextMenu).DataContext = Lst.DataContext;
    }
    

    因此,每次打开 ContextMenu 时,您都在链接 DataContext(因此,如果 Lst 的 DataContext 发生变化,您的 ContextMenu 也会发生变化)

    或者(如果您一定要多次使用它,则更简洁),从这篇文章中获取BindingProxyhttp://tomlev2.wordpress.com/2011/03/21/wpf-how-to-bind-to-data-when-the-datacontext-is-not-inherited/,它会成功的!

    【讨论】:

    • 是的,请查看我在答案末尾发布的文章。 BindingProxy 完美地做到了
    猜你喜欢
    • 2011-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-22
    • 2020-03-10
    • 1970-01-01
    • 2015-03-13
    相关资源
    最近更新 更多