Binding a context menu to a ListBox's Items collection

元气小坏坏 提交于 2019-12-11 02:50:00

问题


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}}" >

回答1:


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}}" >



回答2:


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?



来源:https://stackoverflow.com/questions/1424390/binding-a-context-menu-to-a-listboxs-items-collection

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!