我有一个带有自己的上下文菜单的用户控件,但是我需要向该菜单添加额外的项。
我采用的方法是有一个名为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
然后使用CompositeCollection将控件中的静态菜单项与主机提供的列表组合在一起:
<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>
当我绑定到那个资源时,我看到的是:
- 测试
- (集合 )
第二个菜单项绑定到集合以证明我可以访问它。我有一个测试转换器,我已经添加到菜单项中,它在转换器方法中中断,但是当我将转换器添加到CollectionContainer时,它没有被调用。
最后,我在输出窗口中得到以下错误:
System.Windows。数据错误:4:找不到绑定引用'RelativeSource FindAncestor, AncestorType='System.Windows.Controls '的源。用户控件",AncestorLevel ="1"。BindingExpression:路径= ContextMenuItems;DataItem =零;目标元素是'CollectionContainer' (HashCode=41005040);目标属性为"Collection"(类型为"IEnumerable")
你的"证明"不起作用,因为比较的两个对象显然不相等。你不能在集合容器中使用RelativeSource
或ElementName
绑定,因为不满足必要的条件,即没有NameScope
,因为CollectionContainer是一个抽象对象,没有出现在可视化树中,也没有父对象,通过它可以找到祖先。
如果你可以访问UserControl,你可以使用Binding.Source
和x:Reference
UserControl的名字,为了防止周期性依赖错误,CompositeCollection
应该在UserControl.Resources
中定义,然后使用StaticResource
引用。
。
<UserControl Name="control">
<UserControl.Resources>
<CompositeCollection x:Key="collection">
<!-- ... -->
<CollectionContainer Collection="{Binding ContextMenuItems, Source={x:Reference control}, Converter=...}"/>
</CompositeCollection>
</UserControl.Resources>
<!-- ... -->
<MenuItem ItemsSource="{Binding Source={StaticResource collection}}"/>
</UserControl>