I have a user control with its own context menu, however I need to add additional items to that menu.
The approach I took was to have a dependency property called ContextMenuItems:
Public Shared ReadOnly ContextMenuItemsProperty As DependencyProperty = DependencyProperty.Register("ContextMenuItems", GetType(ObservableCollection(Of MenuItem)), GetType(SmartDataControl), New FrameworkPropertyMetadata(New ObservableCollection(Of MenuItem)))
Public Property ContextMenuItems As ObservableCollection(Of MenuItem)
Get
Return GetValue(ContextMenuItemsProperty)
End Get
Set(ByVal value As ObservableCollection(Of MenuItem))
SetValue(ContextMenuItemsProperty, value)
End Set
End Property
I then used a CompositeCollection to combine the static menu items from the control with the list provided by the host:
<CompositeCollection x:Key="MenuItemsCompositeCollection">
<MenuItem Header="TEST" />
<CollectionContainer Collection="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, Path=ContextMenuItems, Converter={StaticResource TestConverter}}" />
<MenuItem Header="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, Path=ContextMenuItems}" />
</CompositeCollection>
What I see when I bind to that resource is:
- TEST
- (Collection)
The second menu item is bound to the collection to prove I can get to it. I have a test converter that I have added to menu item and it breaks in the converter method, but when I add the converter to the CollectionContainer it doesn’t get called.
Finally, I get the following error in the output window:
System.Windows.Data Error: 4 : Cannot find source for binding with reference ‘RelativeSource FindAncestor, AncestorType=’System.Windows.Controls.UserControl’, AncestorLevel=’1”. BindingExpression:Path=ContextMenuItems; DataItem=null; target element is ‘CollectionContainer’ (HashCode=41005040); target property is ‘Collection’ (type ‘IEnumerable’)
That “proof” of yours does not work because the two objects compared are obviously not equal. You cannot use
RelativeSourceorElementNamebindings in a collection container because the necessary conditions are not met, i.e. there is noNameScopeand since the CollectionContainer is an abtract object which does not appear in the visual tree there also is not parent via which the ancestor could be found.If you have access to the UserControl you can however use the
Binding.Sourceand ax:Referenceto the UserControl’s name, to prevent a cyclical dependecy error theCompositeCollectionshould be defined in theUserControl.Resourcesand then referenced usingStaticResource.e.g.