为什么 ItemsControl 不使用我的 ItemTemplate? [英] Why Does ItemsControl Not Use My ItemTemplate?

查看:14
本文介绍了为什么 ItemsControl 不使用我的 ItemTemplate?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我能够在 ItemsControl 中使用 ItemTemplate 以特定格式呈现项目.但是,如果 ItemsControl 中的项目之一恰好是 TextBox,则呈现该 TextBox 而不是 ItemsTemplate 的实例.据我所知,这适用于任何 FrameworkElement.这是 ItemsControl 的预期行为,还是我做错了什么?

I am able to use an ItemTemplate within an ItemsControl to render items in a specific format. However, if one of the items within the ItemsControl happens to be, say, a TextBox, that TextBox is rendered rather than an instance of the ItemsTemplate. From what I can tell, this is true for any FrameworkElement. Is this intended behavior for an ItemsControl, or am I doing something incorrectly?

示例:

<ItemsControl>
  <ItemsControl.ItemTemplate>
    <DataTemplate>
      <Grid Margin="5">
        <Rectangle Fill="Blue" Height="20" Width="20" />
      </Grid>
    </DataTemplate>
  </ItemsControl.ItemTemplate>
  <ItemsControl.Items>
    <sys:Object />
    <TextBox />
    <sys:Object />
    <Rectangle Fill="Red" Height="20" Width="20" />
  </ItemsControl.Items>
</ItemsControl>

我希望这会显示四个蓝色矩形.我认为任何时候定义了 ItemTemplate 集合中的每个项目都将呈现为模板的一个实例.但是,在这种情况下,将呈现以下内容:一个蓝色矩形后跟一个 TextBox,后跟一个蓝色矩形后跟一个红色矩形.

I expected this to display four blue rectangles. I thought that any time an ItemTemplate has been defined each item in the collection is rendered as an instance of the template. However, in this case the following is rendered: a blue rectangle followed by a TextBox followed by a blue rectangle followed by a red rectangle.

推荐答案

ItemsControl 有一个受保护的成员 IsItemItsOwnContainerOverride,它从项目集合中传递一个对象并返回 true 如果该对象可以直接添加到项目面板而无需生成容器(从而被模板化).

The ItemsControl has a protected member IsItemItsOwnContainerOverride which is passed an object from the items collection and returns true if that object can be added directly to the items panel without a generated container (and thereby be templated).

对于从 UIElement 派生的任何对象,基本实现都返回 true.

The base implementation returns true for any object that derives from UIElement.

要获得您期望的行为,您需要从 ItemsControl 继承并覆盖此方法并使其始终返回 false.不幸的是,事情还没有结束.如果项目是 UIElementPrepareContainerForItemOverride 的默认实现仍然不会将 ItemTemplate 分配给容器,因此您需要将此方法覆盖为嗯:-

To get the behaviour you would expect you would need to inherit from ItemsControl and override this method and have it always return false. Unfortunately thats not the end of the matter. The default implementation of PrepareContainerForItemOverride still doesn't assign the ItemTemplate to the container if the item is a UIElement so you need to override this method as well:-

    protected override bool IsItemItsOwnContainerOverride(object item)
    {
        return false;
    }


    protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
    {
        base.PrepareContainerForItemOverride(element, item);
        ((ContentPresenter)element).ContentTemplate = ItemTemplate;
    }

这篇关于为什么 ItemsControl 不使用我的 ItemTemplate?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆