1

I have a static resource defined as follows:

    <ContextMenu x:Key="TestContextMenu" DataContext="{Binding Path=PlacementTarget, RelativeSource={x:Static RelativeSource.Self}}">
        <MenuItem Command="ApplicationCommands.Cut"/>
        <!--<ContextMenu.ItemsSource>
            <CompositeCollection>
                <MenuItem Command="ApplicationCommands.Cut"/>
            </CompositeCollection>
        </ContextMenu.ItemsSource>-->
    </ContextMenu>

My application works fine like this. However, I want to be able to add extra items to the context menu. So instead of adding menu items I want to use a CompositeCollection and then I run into binding issues. I minimized the problem and ended up with this. When I comment the MenuItem and uncomment the ContextMenu.ItemSource I get this error:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ItemsControl', AncestorLevel='1''. BindingExpression:Path=HorizontalContentAlignment; DataItem=null; target element is 'MenuItem' (Name=''); target property is 'HorizontalContentAlignment' (type 'HorizontalAlignment')

If the datacontext is correct in the first situation why is it not correct anymore in the second situation?

Edit: I don't want to add items to the contextmenu dynamically. I want to use this contextmenu as kind of a 'base context menu' providing cut/copy and paste from a composite collection resource. In some places I want more than just these three and there I could use a custom context menu that use that same collection combined with those extra items. Just to clarify this is the xaml I have in mind, but I cut the problem down to the simpler piece above.

    <CompositeCollection x:Key="TreeViewItemContextMenuItems">
        <MenuItem Command="ApplicationCommands.Cut" CommandTarget="{Binding}"/>
        <MenuItem Command="ApplicationCommands.Copy" CommandParameter="{Binding}"/>
        <MenuItem Command="ApplicationCommands.Paste" CommandParameter="{Binding}"/>
        <Separator/>
        <MenuItem Command="ApplicationCommands.Delete" CommandParameter="{Binding}"/>
    </CompositeCollection>
    <ContextMenu x:Key="TreeViewItemContextMenu" DataContext="{Binding Path=PlacementTarget, RelativeSource={x:Static RelativeSource.Self}}">
        <ContextMenu.ItemsSource>
            <CompositeCollection>
                <CollectionContainer Collection="{StaticResource TreeViewItemContextMenuItems}" />
            </CompositeCollection>
        </ContextMenu.ItemsSource>
    </ContextMenu>

1 Answer 1

1

If you want to dynamically populate ContextMenu the better solution is do to as follows:

<ContextMenu 
    x:Key="TestContextMenu"
    ItemsSource="{Binding MenuItems}">        
</ContextMenu>

I removed DataContext="{Binding Path=PlacementTarget...}}" and added this ItemsSource="{Binding MenuItems}". MenuItems is a property of an object used as a data context. Here is an example of usage:

<Window>
    ...
    <ItemsControl ContextMenu="{StaticResource ResourceKey=TestContextMenu}">
        ...
    </ItemsControl>
</Window

In this case the context menu will inherit a data context from ItemsControl which in turn will inherit a data context from Window.

If you don't want to remove DataContext="{Binding Path=PlacementTarget...}}" then use the following code:

<ContextMenu 
    x:Key="TestContextMenu"
    DataContext="{Binding Path=PlacementTarget, RelativeSource={x:Static RelativeSource.Self}}"
    ItemsSource="{Binding DataContext.MenuItems}">        
</ContextMenu>

EDIT:

You receive these errors because MenuItem controls by default try to bind some of their properties (HorizontalContentAlignment and VerticalContentAlignment) to ItemsControl using RelativeSource. The problem is that their are embeded inside CompositeCollection which doesn't support this kind of binding - see this article.

The problem will occure even if you override this binding in your XAML in this way:

<MenuItem Command="ApplicationCommands.Cut" CommandTarget="{Binding}"
     HorizontalContentAlignment="Center"  VerticalContentAlignment="Center"/>

Probably there is some workaround of this problem but personally I'll ignore these errors. They don't spoil anything in your application, don't they?

Sign up to request clarification or add additional context in comments.

2 Comments

It's not that I want to populate the context menu dynamically. I edited the question to make this clearer.
Thanks for the answer. After some further searching: workaround

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.