无法从我自己的控件中公开内部控件的 属性

Can't expose inner control's property from my own control

我有一个视图想重复使用,它看起来如下:

<UserControl x:Class="Klein.DocumentSample.View.UserControls.CollectionView"
    ...
    <dxr:RibbonPageGroup x:Name="tasksPageGroup" Caption="Customer Tasks">
        <dxr:RibbonPageGroup.Items>
            <dxb:BarButtonItem Content="New" Command="{Binding NewCommand}"  LargeGlyph="{dx:DXImage Image=New_32x32.png}" Glyph="{dx:DXImage Image=New_16x16.png}"/>
            <dxb:BarButtonItem Content="Edit" Command="{Binding EditCommand}" CommandParameter="{Binding SelectedEntity}" LargeGlyph="{dx:DXImage Image=Edit_32x32.png}" Glyph="{dx:DXImage Image=Edit_16x16.png}"/>
            <dxb:BarButtonItem Content="Delete" Command="{Binding DeleteCommand}" CommandParameter="{Binding SelectedEntity}" LargeGlyph="{dx:DXImage Image=Delete_32x32.png}" Glyph="{dx:DXImage Image=Delete_16x16.png}"/>
            <dxb:BarButtonItem Content="Refresh" Command="{Binding RefreshCommand}"  LargeGlyph="{dx:DXImage Image=Refresh_32x32.png}" Glyph="{dx:DXImage Image=Refresh_16x16.png}"/>
        </dxr:RibbonPageGroup.Items>
    </dxr:RibbonPageGroup>
    ...
</UserControl>

此控件的所有用法都会有四个按钮(新建、编辑、删除和刷新)。但是有些用法,除了这些之外,还会有更多的按钮。因此我想让 CollectionView 公开 tasksPageGroup.Items,这样我就可以添加更多按钮,如下所示:

<Window
    <Grid>
        <userControls:CollectionView>
            <userControls:CollectionView.TasksPageGroup>
                <userControls:CollectionView.TasksPageGroup.Items>
                    <!-- This is the 5th button -->
                    <dxb:BarButtonItem Content="Reset" Command="{Binding ResetCommand}"  LargeGlyph="{dx:DXImage Image=Reset_32x32.png}" Glyph="{dx:DXImage Image=Reset_16x16.png}"/>
                </userControls:CollectionView.TasksPageGroup.Items>
        </userControls:CollectionView>
    </Grid>
</Window>

这是我背后的代码:

public partial class CollectionView : UserControl
{
    public RibbonPageGroup TasksPageGroup
    {
        get { return tasksPageGroup; }
    }

    public CollectionView()
    {
        InitializeComponent();
    }
}

如何实现?

所需用法:

<Grid>
    <dxb:BarManager>
        <dxb:BarManager.Items>
            <dxb:BarButtonItem x:Name="testeButtonItem" Content="New" Command="{Binding TesteCommand}"  LargeGlyph="{dx:DXImage Image=New_32x32.png}" Glyph="{dx:DXImage Image=New_16x16.png}"/>
        </dxb:BarManager.Items>
    </dxb:BarManager>
    <userControls:CollectionView>
        <userControls:CollectionView.Tasks>
            <dxb:BarItemLink BarItemName="testeButtonItem" />
        </userControls:CollectionView.Tasks>
    </userControls:CollectionView>
</Grid>

你通常不会那样暴露自己的内心。在 WPF 中,要向外界公开一个 属性,你可以在外面放一个 DependencyProperty

public IList<BarButtonItem> Tasks
    {
        get { return (IList<BarButtonItem >)GetValue(TasksProperty);                }
        set { SetValue(TasksProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Colors.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty TasksProperty =
        DependencyProperty.Register("Tasks", typeof(IList<BarButtonItem>), typeof(CollectionView), new PropertyMetadata(new List<BarButtonItem>()));

现在,小心。将 属性 元数据初始化为这样的实例意味着 该控件的每个实例都将共享同一个集合 。有一个简单的修复方法,只需在构造函数中重新设置它即可:

SetValue(TasksProperty , new List<BarButtonItem>());

现在您可以按预期添加到该集合中了。在您的 Loaded 活动中,枚举集合并将每个项目添加到适当的 Items 集合。

这有利于减少父控件对用户控件的了解,并允许稍后进行绑定。

使用它时,您需要将集合包装在 x:Array 标记中,以便框架知道它是一个集合:

<userControls:CollectionView.Tasks>
    <x:Array>
       ...
    </x:Array>
</userControls:CollectionView.Tasks>