2017-10-10 110 views
1

我正在學習wpf和mvvm,我決定爲自己創建一個Soundboard來練習,到目前爲止它已經很好。 現在我已經創建了一個數據模板,其中程序在指定目錄中找到的每個文件都會創建一個帶有文件名稱的按鈕,然後我可以點擊它來播放。到現在爲止還挺好。 但是我現在試圖創建一個ContextMenu,以便當我想從列表中刪除一個文件時,我可以右鍵單擊並選擇刪除,但即使我具有與常規按鈕完全相同的命令結構,該命令也不起作用。C#wpf數據綁定命令在contextmenu中不起作用

我真的很困惑整個RelativeSource的東西,並已經很高興我的常規'玩'命令在按鈕工作。

如果有人能指出我的方向會很棒。我真的可以對我的具體問題進行解釋,因爲總是似乎以某種方式幫助我更多的是一個通用示例。我試圖閱讀所有相關的問題,但似乎沒有從那裏弄清楚。

我的ItemsControl:

<ItemsControl x:Name="MySounds" ItemsSource="{Binding Sounds}"> 

ItemTemplate:它

<ItemsControl.ItemTemplate> 
       <DataTemplate> 
        <StackPanel> 
         <Button Style="{StaticResource mainButton}" 
           Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ItemsControl}}, Path=DataContext.PlaySound}" 
           CommandParameter="{Binding Path=Tag, RelativeSource={RelativeSource Self}}" 
           Tag="{Binding Path=Name}"> 
          <TextBlock Text="{Binding Path=NormalizedName}" TextWrapping="Wrap" Height="auto" /> 
          <Button.ContextMenu> 
           <ContextMenu> 
            <MenuItem Header="{Binding Path=Name}" 
               Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ItemsControl}}, Path=DataContext.RemoveSound}" 
               CommandParameter="{Binding Path=Tag, RelativeSource={RelativeSource Self}}"> 
             <MenuItem.Icon> 
              <Image Source="\WpfPractice;component\Images\CoffeeArt.png" Width="20" VerticalAlignment="Center"/> 
             </MenuItem.Icon> 
            </MenuItem> 
           </ContextMenu> 
          </Button.ContextMenu> 
         </Button> 
        </StackPanel> 
       </DataTemplate> 
      </ItemsControl.ItemTemplate> 

我有一個通用的RelayCommand在我的視圖模型,所有的作品,真正的問題是剛剛與結合。

+0

你可以嘗試使用'ElementName'而不是'RelativeSource'嗎?爲您的ItemsControl設置一個名稱(如x:Name =「myIC」),然後更新綁定。 – Atlasmaybe

+0

我試過了,但無論我嘗試過什麼,它都不起作用。在我的MenuItem頭文件中,我使用'{binding Path = Name}'獲得了與我的按鈕相同的值,但是同樣的命令似乎不起作用。 –

回答

0

如果您在ButtonTag屬性綁定到ItemsControl,你可以使用的的PlacementTarget屬性綁定到命令ContextMenu

<ItemsControl.ItemTemplate> 
    <DataTemplate> 
     <StackPanel> 
      <Button Style="{StaticResource mainButton}" 
           Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ItemsControl}}, Path=DataContext.PlaySound}" 
           CommandParameter="{Binding Path=Name}" 
           Tag="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ItemsControl}}}"> 
       <TextBlock Text="{Binding Path=NormalizedName}" TextWrapping="Wrap" Height="auto" /> 
       <Button.ContextMenu> 
        <ContextMenu> 
         <MenuItem Header="{Binding Path=Name}" 
            Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ContextMenu}}, Path=PlacementTarget.Tag.DataContext.RemoveSound}" 
            CommandParameter="{Binding Path=Name}"> 
          <MenuItem.Icon> 
           <Image Source="\WpfPractice;component\Images\CoffeeArt.png" Width="20" VerticalAlignment="Center"/> 
          </MenuItem.Icon> 
         </MenuItem> 
        </ContextMenu> 
       </Button.ContextMenu> 
      </Button> 
     </StackPanel> 
    </DataTemplate> 
</ItemsControl.ItemTemplate> 
+0

這似乎已經做到了。 –

+0

你能否詳細說明爲什麼做這個工作?是否因爲Tag現在被設置爲RelativeSource ItemsControl,然後PlacementTarget被設置爲Tag並且又被設置爲DataContext?就像我之前說過的,我對RelativeSource的理解是非常光明的。 –

+0

ContextMenu駐留在它自己的可視化樹中,因此它沒有任何祖先。雖然按鈕。 – mm8

0

您可以嘗試通過它來取代你的命令字符串中的菜單項:

Command="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=DataContext.RemoveSound}"