使用静态标题的ItemsControl

12

我想我有一个相当简单的目标,但似乎无法达成。

我想要实现的是带有标题的ItemsControl(因为我不想要列表的选择功能)。最好是静态标题。

目前,我正在使用一个网格来作为标题,然后将该网格复制到ItemsControl的ItemTemplate(DataTemplate)中,然后将它们放置在网格中的上方。它有点有效,但并不总是很好地对齐等问题。

然后我发现了HeaderedItemsControl,我认为这是一个绝妙的想法,但无法让它工作,它根本不显示标题。 我尝试过以下方法;

  • 只需在Xaml的“Header”中输入文本
  • 在ItemsControl.Header标记内部放置具有静态文本的TextBlocks的网格
  • 将网格放置在HeaderTemplate(Datatemplate)中,并将其绑定到一个简单的对象

我正在Blend中完成所有这些工作,在一个小项目中进行测试,然后再将其移植到生产应用程序中,我只是使用我创建的简单样例数据源。

我可能完全错过了重点,但任何帮助都将不胜感激。

我的当前代码如下,首先是我的HeaderedItemsControl:

<HeaderedItemsControl Header="HeaderedItemsControl"  
        ItemsSource="{Binding Collection, Mode=Default}" 
        ItemTemplate="{DynamicResource ItemsControlDataTemplate}" 
        HeaderTemplate="{DynamicResource ItemsControlHeaderDataTemplate}"/>

然后我得到了一个预期工作的ItemTemple

<DataTemplate x:Key="ItemsControlDataTemplate">
        <Grid d:DesignWidth="268">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="0.754*"/>
                <ColumnDefinition Width="0.246*"/>
            </Grid.ColumnDefinitions>
            <TextBlock Text="{Binding Property1, Mode=Default}" TextWrapping="Wrap" d:LayoutOverrides="Height" HorizontalAlignment="Stretch" Margin="0" />
            <TextBlock Text="{Binding Property2, Mode=Default}" TextWrapping="Wrap" d:LayoutOverrides="Height" Grid.Column="1" HorizontalAlignment="Left" Margin="0" />
        </Grid>
    </DataTemplate>

然后是标题,明显违反其工作原则,我已经尝试过使用绑定和在TextBlock.Text属性中使用纯文本

<DataTemplate x:Key="ItemsControlHeaderDataTemplate">
        <Grid d:DesignWidth="268">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="0.754*"/>
                <ColumnDefinition Width="0.246*"/>
            </Grid.ColumnDefinitions>
            <TextBlock Text="{Binding Header.Header1, Mode=Default, Source={StaticResource SampleDataSource6}}" TextWrapping="Wrap" HorizontalAlignment="Stretch" Margin="0"/>
            <TextBlock Text="{Binding Header.Header2, Mode=Default, Source={StaticResource SampleDataSource6}}" TextWrapping="Wrap" d:LayoutOverrides="Height" Grid.Column="1" HorizontalAlignment="Left" Margin="0"/>
        </Grid>
    </DataTemplate>
2个回答

11

HeaderedItemsControl没有默认样式,因此它只是使用基本ItemsControl类的模板,该模板不会呈现任何标题。 它仅由框架用作MenuItem、ToolBar和TreeViewItem的基类,这些类定义了自己的模板。 您可以创建自己的模板,其中包括一个ContentPresenter用于标题:

<HeaderedItemsControl ItemsSource="{Binding}" Header="Some text">
    <HeaderedItemsControl.Template>
        <ControlTemplate TargetType="HeaderedItemsControl">
            <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
                <DockPanel>
                    <ContentPresenter DockPanel.Dock="Top" ContentSource="Header" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                    <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                </DockPanel>
            </Border>
        </ControlTemplate>
    </HeaderedItemsControl.Template>
</HeaderedItemsControl>

如果您只在一个地方使用它,那么使用普通的ItemsControl并直接包含标题在控件模板中可能会更容易。

此外,看起来您正在尝试拥有两个网格,其列具有相同的宽度。您可能需要查看WPF中的Grid Size Sharing。如果在父控件上设置Grid.IsSharedSizeScope,则可以在不同网格的列上设置SharedSizeGroup以使它们具有相同的宽度。


谢谢您,先生。您的回答真的很有帮助。最终,我为HeaderedItemsControl创建了一个样式,并像您建议的那样添加了ContentPresenter,其中ContentSource = header属性。这样,我可以在应用程序中使用它在所有ItemsControl上,并只需在HeaderedItemsControl.Header标记中添加一个带有TextBlock的网格即可。关于您对Grid大小共享的建议,我会进行测试,但不确定它是否能够正常工作,因为一个网格位于DataTemplate中,而另一个则位于ItemsControl的标题中,但我会进行测试并反馈。 - Organ Grinding Monkey

0

昨天遇到了类似的问题 - 对于HeaderedContentControl,请尝试设置Header属性而不是HeaderTemplate属性。

我发现通过HeaderTemplate实现绑定是不可能的 - 内容可以正确地绑定。如果有人能解释一下原因,我会非常感兴趣。

希望上述解决方法对您有所帮助。

Chris


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接