我在做一些看起来非常简单的事情时却遇到了麻烦,但事实并非如此。
我有一个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和播放列表都有一个名称属性。
因此两个绑定之间存在某种冲突,我不知道如何解决它。
提前感谢您的回复。
答案 0 :(得分:1)
struct MyDataNode {
MyDataNode* rbe_left;
MyDataNode* rbe_ight;
char rbe_color;
// data to be stored
};
template <class Entry>
class RbTree {
// implementation
};
// usage:
RbTree<MyDataNode> treeInstance;
与可视树分离,因此无法以正常方式在其范围内使用ContextMenu
或ElementName
进行绑定。你需要一些代理技术来弥补切割。这里我们有RelativeSource
元素,它可以继承数据上下文,并允许绑定到可视化树,即使在这种情况下也很容易。为方便起见,我们应该使用Freezable
因为它的Value可以接受所有类型的对象。如果您关心名称,那么您可以定义自己的自定义Freezable对象。
DiscreteObjectKeyFrame
修改 - 这是为了帮助您了解如何混合播放列表和SelectedFolder中的信息:
<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>
如您所见,添加的菜单项(<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
将DataContext
设置为Window
个实例。因此,在没有明确proxy
和Source
和RelativeSource
设置的范围内使用的所有Binding都将获得DataContext(您的窗口)的已解析源。