我有一个带有自己的上下文菜单的用户控件,但是我需要在该菜单中添加其他项目。
我采用的方法是拥有一个名为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.Data错误:4:无法找到绑定源,引用'RelativeSource FindAncestor,AncestorType ='System.Windows.Controls.UserControl',AncestorLevel ='1''。 BindingExpression:路径= ContextMenuItems;的DataItem = NULL; target元素是'CollectionContainer'(HashCode = 41005040); target属性是'Collection'(类型'IEnumerable')
答案 0 :(得分:2)
你的“证明”不起作用,因为比较的两个对象显然不相等。您不能在集合容器中使用RelativeSource
或ElementName
绑定,因为不满足必要的条件,即没有NameScope
,因为CollectionContainer是一个abtract对象,它不出现在视觉树也没有父母通过它可以找到祖先。
如果您有权访问UserControl,则可以使用Binding.Source
和x:Reference
到UserControl的名称,以防止出现周期性依赖性错误,CompositeCollection
应在UserControl.Resources
中定义{1}}然后使用StaticResource
引用。
e.g。
<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>