C# 上下文菜单中不起作用的命令

C# 上下文菜单中不起作用的命令,c#,wpf,xaml,mvvm,C#,Wpf,Xaml,Mvvm,嗯,我有一个WPF项目,我正在使用VisualStudio2010。我使用的是C#和XAML,我使用的是MVVM模式 我的问题一定很简单,但我就是不明白为什么它不起作用 好的,我有一个带有列表框的项目。在该列表框中有许多聊天节点;每一个都在视觉上表现出来。ChatNode的可视元素如下所示: <ControlTemplate x:Key="NodeVisualTemplate"> <Grid> <Border

嗯,我有一个WPF项目,我正在使用VisualStudio2010。我使用的是C#和XAML,我使用的是MVVM模式

我的问题一定很简单,但我就是不明白为什么它不起作用

好的,我有一个带有列表框的项目。在该列表框中有许多聊天节点;每一个都在视觉上表现出来。ChatNode的可视元素如下所示:

 <ControlTemplate x:Key="NodeVisualTemplate">
            <Grid>
                <Border BorderThickness="2" Margin="2" CornerRadius="5,5,5,5" BorderBrush="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}, Path=DataContext.SelectionMode, Converter={StaticResource SelectionModeToColourConverter}}" ContextMenu="{StaticResource ChatNodeMenu}">
                    <StackPanel Opacity="{Binding IsInvisibleNode, Converter={StaticResource ResourceKey=VisibleToOpacityConverter}}">
                        <TextBlock Text="Test" Background="AntiqueWhite"/>
                        <TextBlock Text="{Binding Path=NodeText}" Background="Aqua"/>
                        <StackPanel Orientation="Horizontal">
                            <TextBox Text="Type here" MinWidth="50"/>
                            <Image Source="{StaticResource ImgFolder}" Margin="0,0,5,0" Width="32" Height="32"/>
                        </StackPanel>
                    </StackPanel>
                </Border>
            </Grid>
        </ControlTemplate>
此代码位于ListBoxItem内部,能够找到父ListBox,然后访问其属性。这个很好用。该属性位于名为ChatNodeListViewModel的视图模型中,如下所示:

private int _selectionMode = 0;
    public int SelectionMode
    {
        get { return _selectionMode; }
        set
        {
            if (_selectionMode != value)
            {
                _selectionMode = value;
                RaisePropertyChanged("SelectionMode");
            }
        }
    }
我特别提到它是因为另一个几乎相同的东西不起作用,即使这个BorderBrush代码起作用

所以,继续讨论不起作用的部分

在上面的同一个控制模板中,我们看到一个名为“ChatNodeMenu”的上下文菜单。详情如下:

<ContextMenu x:Key="ChatNodeMenu" >
            <MenuItem Header="Remove" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}, Path=DataContext.RemoveChatNodeCommand}" />
        </ContextMenu>
在我的代码中,我也在很多地方使用过这个,除了这个,它每次都有效

所以,要么是代码中有错误,要么是一个简单的错误。我已经检查了命令的名称,并多次重新复制了它。我已经检查了代码的其他部分,其中我使用了相同的代码,但我看不出任何错误。我已经清理并重建了我的项目以防万一


如果有人敢猜,我会很高兴的。

列表框不是
上下文菜单
的视觉祖先,但是您可以将
边框
标记
属性设置为
列表框
,然后绑定到
上下文菜单
放置目标

<Border ... Tag="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}" ContextMenu="{StaticResource ChatNodeMenu}">




如何将ContextMenu应用于哪个元素?我通常解决这些问题的方法是将绑定输出到标签中(或读取绑定错误日志)。你也应该这样做。通常,通过这种方式,您可以检测到大多数涉及使用wpfIf的问题。如果查看发布代码的顶部(控件模板),边框的最终属性是ContextMenu。@Dbl我不知道您可以这样做。我不知道该怎么办。您能提供一些关于如何做到这一点的更多信息吗?@thefiithfullerner Extras/Options/debug/OutputWindow/Wpf/Databindings/all祝福您,先生。
void RemoveChatNodeExecute()
    {
        MessageBox.Show("Remove chat node");
        return;
    }

    bool CanRemoveChatNode()
    {
        return true;
    }

    public ICommand RemoveChatNodeCommand { get { return new RelayCommand(RemoveChatNodeExecute, CanRemoveChatNode); } }
<Border ... Tag="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}" ContextMenu="{StaticResource ChatNodeMenu}">
<MenuItem Header="Remove" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}, Path=PlacementTarget.Tag.DataContext.RemoveChatNodeCommand}" />