Binding a context menu to a collection of ListBox items

I am trying to create a context menu for a list box that displays items in the context menu from the list. I can accomplish this 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 is great for one list. However, when I have a second list, the context menu continues to display items from the first list. In other words, the ItemSource of the context menu does not change. Only the first time the context menu is open is the ItemsSource property. 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 style because I have many list instances and don't want to define a separate context menu for each list.

UPDATE: I finally figured out how to fix this. I just need to bind to PlacementTarget.Items objects and use my own source, instead of using find's original relative source.

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

      

+2


source to share


2 answers


Found the answer, I just need to bind to PlacementTarget.Items objects and use original source rather than use relative source-source-ancestors.



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

      

+1


source


I think the problem you are having is with the context menu being part of a different visual tree. That is, you cannot find the ancestor of the ListBox because it is not the main ancestor of the context menu.



If you look at the Visual Studio debug panel, you will see some warnings about a not working required expression. You?

0


source







All Articles