2017-08-07 42 views
2

那麼,我有一個WPF項目,並且正在使用Visual Studio 2010.我正在使用C#和XAML,並且正在使用MVVM模式。從不起作用的上下文菜單中的命令

我有問題必須是簡單的,但我不明白爲什麼它不工作。

好的,所以我有一個ListBox項目。在那個ListBox中有很多ChatNodes;每個視覺呈現。 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> 

我將您的注意力吸引到BorderBrush邊框。我將在這裏再次展示:

BorderBrush="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}, Path=DataContext.SelectionMode, Converter={StaticResource SelectionModeToColourConverter}}" 

此代碼位於ListBoxItem中,並且能夠找到父列表框,然後訪問它的一個屬性。這工作正常。該物業是在一個視圖模型稱爲ChatNodeListViewModel,看起來像這樣:

private int _selectionMode = 0; 
    public int SelectionMode 
    { 
     get { return _selectionMode; } 
     set 
     { 
      if (_selectionMode != value) 
      { 
       _selectionMode = value; 
       RaisePropertyChanged("SelectionMode"); 
      } 
     } 
    } 

我說出來,特別是因爲另一件事是幾乎相同的不工作,即使這BorderBrush代碼工作。

因此,對不工作的部分。

在上面的那個ControlTemplate中,我們看到一個叫做'ChatNodeMenu'的ContextMenu。這是如下:

<ContextMenu x:Key="ChatNodeMenu" > 
      <MenuItem Header="Remove" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}, Path=DataContext.RemoveChatNodeCommand}" /> 
     </ContextMenu> 

它具有相同的綁定,只有這次它是一個命令稱爲'RemoveChatNodeCommand'。該菜單確實出現在ChatNode上,右鍵單擊,但該命令不運行。我實際上在我的項目的其他部分使用了幾乎相同的代碼,所以我認爲這是正確的......但顯然在某處存在錯誤。

那麼這個命令在哪裏?這是被稱爲「ChatNodeListViewModel」視圖模型,我將在此介紹它:

void RemoveChatNodeExecute() 
    { 
     MessageBox.Show("Remove chat node"); 
     return; 
    } 

    bool CanRemoveChatNode() 
    { 
     return true; 
    } 

    public ICommand RemoveChatNodeCommand { get { return new RelayCommand(RemoveChatNodeExecute, CanRemoveChatNode); } } 

我也曾在我的代碼中的許多地方使用這個和它的工作每次但是這一個。

所以,無論是代碼中的錯誤還是一個簡單的錯誤。我已經檢查過命令的名稱並重新複製了好幾次。我已經檢查過我的代碼中使用相同代碼的其他部分,但是我看不到任何錯誤。我已經清理並重建了我的項目以防萬一。

如果有人可以冒險猜測,我會很高興。

+0

如何你應用ContextMenu和哪個元素? – mm8

+0

我通常解決這些問題的方式是將我的綁定輸出到標籤中(或通過讀取綁定錯誤日誌)。你應該嘗試做同樣的事情。通常用這種方法,你可以檢測到涉及使用wpf的大多數問題。 – Dbl

+0

如果您查看發佈代碼的頂部(控制模板),Border的最終屬性是ContextMenu。 – TheFaithfulLearner

回答

2

ListBox不是ContextMenu的視覺祖先,但你可以在BorderTag屬性設置爲ListBox,然後綁定到ContextMenuPlacementTarget

<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}" /> 
+0

祝福您先生。 – TheFaithfulLearner