将上下文菜单绑定到 ListBox 的 Items 集合

发布于 2024-08-04 22:33:59 字数 2043 浏览 4 评论 0原文

我正在尝试为列表框创建一个上下文菜单,该列表框显示列表框中上下文菜单中的元素。我可以通过使用以下 XAML 来完成此任务:

<Window.Resources>        
    <ContextMenu x:Key="contextMenu" 
                 ItemsSource="{Binding Items, 
        RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}}" >
        <ContextMenu.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Content}"/>
            </DataTemplate>
        </ContextMenu.ItemTemplate>
    </ContextMenu>

    <Style TargetType="{x:Type ListBox}">
        <Setter Property="ContextMenu" Value="{StaticResource contextMenu}"/>            
    </Style>
</Window.Resources>

这对于一个列表框非常有效。但是,当我有第二个列表框时,上下文菜单会继续显示第一个列表框中的元素。换句话说,上下文菜单的 ItemsSource 不会改变。仅在第一次打开上下文菜单时才会设置 ItemsSource 属性。例如:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>

    <ListBox x:Name="first" >
        <ListBoxItem>First 1</ListBoxItem>
        <ListBoxItem>First 2</ListBoxItem>
        <ListBoxItem>First 3</ListBoxItem>
        <ListBoxItem>First 4</ListBoxItem>
        <ListBoxItem>First 5</ListBoxItem>
    </ListBox>
    <ListBox x:Name="second" Grid.Column="2" >
        <ListBoxItem>Second 1</ListBoxItem>
        <ListBoxItem>Second 2</ListBoxItem>
        <ListBoxItem>Second 3</ListBoxItem>
        <ListBoxItem>Second 4</ListBoxItem>
        <ListBoxItem>Second 5</ListBoxItem>
    </ListBox>    
</Grid>

我想在样式中设置上下文菜单,因为我有许多列表框实例,并且不想为每个列表框定义单独的上下文菜单。

更新: 我终于弄清楚如何解决它。我只需要绑定到 PlacementTarget.Items 并使用自相关源,而不是使用查找祖先相对源。

<ContextMenu x:Key="contextMenu" 
  ItemsSource="{Binding PlacementTarget.Items, 
  RelativeSource={RelativeSource Self}}" >

I'm trying to create a context menu for a list box which displays elements in the context menu from the list box. I am able to accomplish this by using the following XAML:

<Window.Resources>        
    <ContextMenu x:Key="contextMenu" 
                 ItemsSource="{Binding Items, 
        RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}}" >
        <ContextMenu.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Content}"/>
            </DataTemplate>
        </ContextMenu.ItemTemplate>
    </ContextMenu>

    <Style TargetType="{x:Type ListBox}">
        <Setter Property="ContextMenu" Value="{StaticResource contextMenu}"/>            
    </Style>
</Window.Resources>

This works great for one list box. However, when I have a second list box, the context menu keeps showing the elements from the first list box. In other words, the ItemsSource of the context menu does not change. Only the first time that the context menu is opened is the ItemsSource property set. For example:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>

    <ListBox x:Name="first" >
        <ListBoxItem>First 1</ListBoxItem>
        <ListBoxItem>First 2</ListBoxItem>
        <ListBoxItem>First 3</ListBoxItem>
        <ListBoxItem>First 4</ListBoxItem>
        <ListBoxItem>First 5</ListBoxItem>
    </ListBox>
    <ListBox x:Name="second" Grid.Column="2" >
        <ListBoxItem>Second 1</ListBoxItem>
        <ListBoxItem>Second 2</ListBoxItem>
        <ListBoxItem>Second 3</ListBoxItem>
        <ListBoxItem>Second 4</ListBoxItem>
        <ListBoxItem>Second 5</ListBoxItem>
    </ListBox>    
</Grid>

I would like to set the context menu in a Style because I have many instances of a listbox and do not want to define a separate context menu for each listbox.

UPDATE:
I finally figured out how to fix it. I just need to bind to the PlacementTarget.Items and using a self relative source instead of using a find ancestor relative source.

<ContextMenu x:Key="contextMenu" 
  ItemsSource="{Binding PlacementTarget.Items, 
  RelativeSource={RelativeSource Self}}" >

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

桃酥萝莉 2024-08-11 22:33:59

找到答案,我只需要绑定到 PlacementTarget.Items 并使用自相关源,而不是使用查找祖先相对源。

<ContextMenu x:Key="contextMenu" 
  ItemsSource="{Binding PlacementTarget.Items, 
  RelativeSource={RelativeSource Self}}" >

Found the answer, I just need to bind to the PlacementTarget.Items and using a self relative source instead of using a find ancestor relative source.

<ContextMenu x:Key="contextMenu" 
  ItemsSource="{Binding PlacementTarget.Items, 
  RelativeSource={RelativeSource Self}}" >
扶醉桌前 2024-08-11 22:33:59

我认为您在这里遇到的问题是由于上下文菜单是不同视觉树的一部分。也就是说,您无法找到 ListBox 祖先,因为它实际上不是上下文菜单的祖先。

如果您查看 Visual Studio 的调试面板,您应该会看到一些有关失败的绑定表达式的警告。你?

I think the issue you're having here is due to the fact that the context menu is part of a different visual tree. That is, you cannot find the ListBox ancestor because it is not actually an ancestor of the context menu.

If you look at the debug panel of Visual Studio, you should see some warnings about the failing binding expression. Do you?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文