使用ContentPresenter和ItemsPresenter进行自定义控制

时间:2014-07-24 08:44:16

标签: c# wpf xaml custom-controls

我构建了一个自定义控件,其中包含两个内容区域,如下所示:

+-------------+
| L |         |
| o |  Main   |
| g | Content |
| o |         |
+---+---------+
| Interaction |
+-------------+

我是通过继承Control并添加两个依赖项属性MainContentUserInteractions来实现此目的的。使用控件时,我会这样做:

<controls:ScreenControl>
    <controls:ScreenControl.MainContent>
        <TextBlock>Some content goes here</TextBlock>
    </controls:ScreenControl.MainContent>
    <controls:ScreenControl.UserInteractions>
        <Button>Do something</Button>
    </controls:ScreenControl.UserInteractions>
</controls:InstallerScreenControl>

相应的控件模板看起来略微简化,如下所示:

<Style TargetType="{x:Type controls:ScreenControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type controls:ScreenControl}">
                <DockPanel Width="530">
                    <DockPanel DockPanel.Dock="Top">
                        <!-- Some static content -->
                        <ContentPresenter Content="{Binding MainContent, RelativeSource={...}}"
                                          DataContext="{Binding DataContext, RelativeSource={...}}"/>
                    </DockPanel>
                    <DockPanel DockPanel.Dock="Bottom" Background="LightGray" Height="50">
                        <StackPanel DockPanel.Dock="Right" Orientation="Horizontal" HorizontalAlignment="Right">
                            <ContentPresenter Content="{Binding UserInteractions, RelativeSource={...}}" 
                                              DataContext="{Binding DataContext, RelativeSource={...}}" />
                        </StackPanel>
                    </DockPanel>
                </DockPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

现在,我想在UserInteractions区域中允许多个元素。但是,ContentPresenter仅允许单个元素。从阅读开始,我似乎需要使用ItemsPresenter,但这只有在我继承ItemsControl时才有效吗?

我尝试将UserInteractions依赖项属性的类型设置为ObservableCollection<UIElement>(我发现的大多数文章只是将其设置为object,这就是我所拥有的),这可用于 - 到目前为止,几个孩子没有编译错误,但在渲染时只显示(Collection),而不是实际的按钮。

我错过了什么?

1 个答案:

答案 0 :(得分:2)

如果UserInteractions是UI元素的集合,则应该开箱即用:

<ItemsControl ItemsSource="{Binding UserInteractions, RelativeSource={...}}"/>

如果UserInteraction对象是纯数据对象,您还必须定义ItemTemplate

<ItemsControl ItemsSource="{Binding UserInteractions, RelativeSource={...}}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            ...
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>