簡體   English   中英

將集合綁定到 ContextMenu 子菜單

[英]Binding collection to ContextMenu submenu

我在做一些看起來很容易但實際上並非如此的事情時遇到了麻煩。

我有一個 ListView,我在其中綁定了一個 ObservableCollection,我希望在我右鍵單擊該 ListView 的元素時出現一個 ContextMenu。

在那個 ContextMenu 中,我想要一個 MenuItem,上面寫着“添加到播放列表”,里面是我所有播放列表的列表。

所以我做了這個,這對我來說是正確的:

<ListView Grid.Row="0" Grid.Column="1" x:Name="ListBoxSelectedFolder" ItemsSource="{Binding Path=SelectedFolder.PlayableElements}">
      <ListView.Resources>
        <ContextMenu x:Key="ContextMenu">
          <MenuItem Header="Add to" ItemsSource="{Binding Path=Playlists}">
            <MenuItem Header="{Binding Name}"/>
          </MenuItem>
          <MenuItem Header="Remove from All" />
        </ContextMenu>
      <Style TargetType="{x:Type ListViewItem}">
         <Setter Property="ContextMenu" Value="{StaticResource ContextMenu}"/>
    </Style>
      </ListView.Resources>
      <ListView.View>
        <GridView>
            <GridViewColumn Header="Type" DisplayMemberBinding="{Binding Extension}" />
            <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" />
        </GridView>
    </ListView.View>
</ListView>

問題是我在子菜單中唯一得到的是我單擊的項目的名稱:不知何故,它與 ListView 的集合 SelectedFolder.PlayableElements 綁定,因為 SelectedFolder.PlayableElements 和 Playlists 都有一個 Name 屬性。

所以這兩個綁定之間存在某種沖突,我不知道如何解決。

預先感謝您的回復。

ContextMenu與可視化樹分離,因此無法以正常方式在其范圍內與ElementNameRelativeSource綁定。 您需要一些代理技術來橋接切割。 這里我們有Freezable元素,它可以繼承數據上下文,並且即使在這種情況下也可以輕松地綁定到可視化樹。 為方便起見,我們應該使用DiscreteObjectKeyFrame因為它的 Value 可以接受所有類型的對象。 如果您關心名稱,那么您可以定義自己的自定義 Freezable 對象。

<ListView Grid.Row="0" Grid.Column="1" x:Name="ListBoxSelectedFolder" ItemsSource="{Binding Path=SelectedFolder.PlayableElements}">
  <ListView.Resources>
    <DiscreteObjectKeyFrame x:Key="proxy" Value="{Binding Playlists, RelativeSource={RelativeSource AncestorType=Window}}"/>
    <ContextMenu x:Key="ContextMenu">
      <MenuItem Header="Add to" ItemsSource="{Binding Value, Source={StaticResource proxy}}">
         <MenuItem.ItemTemplate>
             <DataTemplate>
                 <TextBlock Text="{Binding Name}"/>
             </DataTemplate>
         </MenuItem.ItemTemplate>
      </MenuItem>
      <MenuItem Header="Remove from All" />
    </ContextMenu>
    <Style TargetType="{x:Type ListViewItem}">
     <Setter Property="ContextMenu" Value="{StaticResource ContextMenu}"/>
    </Style>
  </ListView.Resources>
  <!-- ... -->
</ListView>

編輯- 這是為了幫助您了解如何混合播放列表和 SelectedFolder 中的信息:

<ListView Grid.Row="0" Grid.Column="1" x:Name="ListBoxSelectedFolder" ItemsSource="{Binding Path=SelectedFolder.PlayableElements}">
  <ListView.Resources>
    <DiscreteObjectKeyFrame x:Key="proxy" Value="{Binding RelativeSource={RelativeSource AncestorType=Window}}"/>
    <ContextMenu x:Key="ContextMenu" DataContext="{Binding Value, Source={StaticResource proxy}}">
      <MenuItem Header="Add to" ItemsSource="{Binding Playlists}">
         <MenuItem.ItemTemplate>
             <DataTemplate>                     
                 <TextBlock Text="{Binding Name}"/>        
             </DataTemplate>
         </MenuItem.ItemTemplate>
      </MenuItem>
      <MenuItem Header="Playable elements" ItemsSource="{Binding SelectedFolder.PlayableElements}"/>
      <MenuItem Header="Remove from All" />
    </ContextMenu>
    <Style TargetType="{x:Type ListViewItem}">
     <Setter Property="ContextMenu" Value="{StaticResource ContextMenu}"/>
    </Style>
  </ListView.Resources>
  <!-- ... -->
</ListView>

如您所見,添加的菜單項(在Remove from all正上方)將其ItemsSource設置為SelectedFolder.PlayableElements ContextMenu現在通過proxy將其DataContext設置為Window實例。 因此,在其范圍內使用的所有綁定都沒有明確的SourceRelativeSource以及ElementName集將獲得 DataContext(您的窗口)的解析源。

使用您展示的代碼,您只需將另一個菜單項綁定到 name 屬性。 我猜你要找的是MenuItemItemTemplate屬性。 通過這種方式,您可以定義應為該菜單項的每個子項顯示哪些數據。 檢查下面的標記:

<ListView Grid.Row="0" Grid.Column="1" x:Name="ListBoxSelectedFolder" ItemsSource="{Binding Path=SelectedFolder.PlayableElements}">
          <ListView.Resources>
            <ContextMenu x:Key="ContextMenu">
              <MenuItem Header="Add to" ItemsSource="{Binding Path=Playlists}">
                 <MenuItem.ItemTemplate>
                    <DataTemplate>
                        <MenuItem Header="{Binding Path=Name}" />
                    </DataTemplate>
                 </MenuItem.ItemTemplate>
                <MenuItem Header="{Binding Name}"/>
              </MenuItem>
              <MenuItem Header="Remove from All" />
            </ContextMenu>
          <Style TargetType="{x:Type ListViewItem}">
             <Setter Property="ContextMenu" Value="{StaticResource ContextMenu}"/>
        </Style>
          </ListView.Resources>
          <ListView.View>
            <GridView>
                <GridViewColumn Header="Type" DisplayMemberBinding="{Binding Extension}" />
                <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" />
            </GridView>
        </ListView.View>
    </ListView>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM