将集合依赖属性数据绑定到用户控件中的菜单
我有一个带有自己的上下文菜单的用户控件,但是我需要向该菜单添加其他项目。
我采取的方法是拥有一个名为 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>
当我绑定到该资源时,我看到的是:
- TEST
- (集合)
第二个菜单项与集合绑定,以证明我可以访问它。我有一个测试转换器,已添加到菜单项,并且它在转换器方法中中断,但是当我将转换器添加到 CollectionContainer 时,它不会被调用。
最后,我在输出窗口中收到以下错误:
System.Windows.Data 错误:4:无法找到与引用“RelativeSource FindAncestor、AncestorType='System.Windows.Controls.UserControl”、AncestorLevel='1'' 进行绑定的源。 BindingExpression:Path=ContextMenuItems;数据项=空;目标元素是“CollectionContainer”(HashCode=41005040);目标属性是“Collection”(类型“IEnumerable”)
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')
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你的那个“证明”不起作用,因为比较的两个对象显然不相等。您无法在集合容器中使用
RelativeSource
或ElementName
绑定,因为未满足必要条件,即不存在NameScope
并且由于 CollectionContainer 是一个抽象对象,不会出现在可视化树中也没有父母通过它可以找到祖先。如果您有权访问 UserControl,则可以使用
Binding.Source
和x:Reference
指向 UserControl 的名称,为了防止循环依赖错误,应在UserControl 中定义
,然后使用CompositeCollection
。资源StaticResource
进行引用。例如
That "proof" of yours does not work because the two objects compared are obviously not equal. You cannot use
RelativeSource
orElementName
bindings in a collection container because the necessary conditions are not met, i.e. there is noNameScope
and 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.Source
and ax:Reference
to the UserControl's name, to prevent a cyclical dependecy error theCompositeCollection
should be defined in theUserControl.Resources
and then referenced usingStaticResource
.e.g.