将集合依赖项属性绑定到用户控件中的菜单



我有一个带有自己的上下文菜单的用户控件,但是我需要向该菜单添加额外的项。

我采用的方法是有一个名为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")

你的"证明"不起作用,因为比较的两个对象显然不相等。你不能在集合容器中使用RelativeSourceElementName绑定,因为不满足必要的条件,即没有NameScope,因为CollectionContainer是一个抽象对象,没有出现在可视化树中,也没有父对象,通过它可以找到祖先。

如果你可以访问UserControl,你可以使用Binding.Sourcex: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>

最新更新