在 ItemsControl 中的每个项目周围包裹一些东西

发布于 2024-09-28 10:22:26 字数 824 浏览 10 评论 0原文

假设我有不同类的对象的集合。每个类在资源文件中都有其 UserControl DataTemplated。

现在我想使用 ItemsControl 来显示集合,但我希望每个项目周围有一个边框或扩展器。

我希望这样的事情能够工作:

<ItemsControl ItemsSource="{Binding MyObjects}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Border BorderBrush="Black" BorderThickness="3">
                <ContentPresenter/>
            </Border>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

但是 ContentPresenter 似乎选择了 ItemTemplate,因为我遇到了堆栈溢出。

如何获取 ItemTemplate 中每个 Item 的 DataTemplate?

Let's say I have a collection of objects of different classes. Each class has its UserControl DataTemplated in a resource file.

Now I want to use ItemsControl to display the collection, but I want an Border or Expander around each item.

I would expect something like this to work:

<ItemsControl ItemsSource="{Binding MyObjects}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Border BorderBrush="Black" BorderThickness="3">
                <ContentPresenter/>
            </Border>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

But the ContentPresenter seems to pick ItemTemplate, because I get a stack overflow.

How do I get each Item's DataTemplate inside the ItemTemplate?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

樱花细雨 2024-10-05 10:22:26

通常,您可能会考虑通过模板化项目容器来做到这一点。问题是“通用”ItemsControl 使用ContentPresenter 作为其项目容器。因此,即使您尝试使用 ItemContainerStyle 设置样式,您也会发现无法提供模板,因为 ContentPresenter 不支持控件模板(它确实支持数据模板,但没有用)这里)。

要使用模板化容器,您必须从 ItemsControl 派生,如下所示 示例

另一种选择可能只是使用 ListBox 控件。然后,您可以通过样式设置 ListBoxItem 模板来提供自定义模板。

您可以在此处阅读有关容器的更多信息 .

(经过您的许可,我将解决方案添加到您的答案中,古格)

    <ListBox ItemsSource="{Binding MyObjects}" Grid.Column="1">
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal"/>
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
        <ListBox.ItemContainerStyle>
            <Style TargetType="{x:Type ListBoxItem}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type ListBoxItem}">
                            <Border BorderBrush="Black" BorderThickness="3">
                                <ContentPresenter/>
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </ListBox.ItemContainerStyle>
    </ListBox>

Normally you might consider doing this by templating the item container. The problem is the "generic" ItemsControl uses the ContentPresenter as its item container. So even if you try and set a style with ItemContainerStyle you will find you cannot supply a template because the ContentPresenter does not support control templating (it does support data templating but no use here).

To use a templatable container you will have to derrive from ItemsControl like in this example.

An alternative might be just to use the ListBox control instead. Then you can just provide a custom template by setting a ListBoxItem template via a style.

You can read more about containers here .

(With your permissen I'm adding the solution to your answer, Guge)

    <ListBox ItemsSource="{Binding MyObjects}" Grid.Column="1">
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal"/>
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
        <ListBox.ItemContainerStyle>
            <Style TargetType="{x:Type ListBoxItem}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type ListBoxItem}">
                            <Border BorderBrush="Black" BorderThickness="3">
                                <ContentPresenter/>
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </ListBox.ItemContainerStyle>
    </ListBox>
余生再见 2024-10-05 10:22:26

我只需执行以下操作:

<ItemsControl.ItemTemplate>
    <DataTemplate>
        <Border BorderBrush="Black" BorderThickness="3">
            <ContentControl Content={Binding} />
        </Border>
    </DataTemplate>
</ItemsControl.ItemTemplate>

由于 DataTemplate 标记内的数据上下文是源集合中的一个项目,因此我们可以使用 ContentControl 来显示该项目。 {Binding} 意味着我们要绑定到整个数据上下文。您的项目的所有 DataTemplate 都将以与我们未指定 ItemsControl.ItemTemplate 相同的方式隐式应用。

I'd just do the following:

<ItemsControl.ItemTemplate>
    <DataTemplate>
        <Border BorderBrush="Black" BorderThickness="3">
            <ContentControl Content={Binding} />
        </Border>
    </DataTemplate>
</ItemsControl.ItemTemplate>

As data context inside DataTemplate tag is an item from the source collection, we can use a ContentControl to display this item. {Binding} means that we're binding to the whole data context. All DataTemplates for your items will be implicitly applied in the same way as if we didn't specify ItemsControl.ItemTemplate.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文