为什么ItemsControl不使用我的ItemTemplate?

Dre*_*rew 9 silverlight wpf itemtemplate itemscontrol

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

一个例子:

<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>
Run Code Online (Sandbox Code Playgroud)

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

Ant*_*nes 14

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

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

要获得您期望的行为,您需要继承ItemsControl并覆盖此方法,并始终返回false.不幸的是,这不是问题的结束.如果项目是a ,则默认实现PrepareContainerForItemOverride仍然不会分配ItemTemplate给容器,UIElement因此您还需要覆盖此方法: -

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


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

  • 截至2015年,他们可能已经修复了第二部分.使用.NET 4.5.1中的WPF,如果我为`IsItemItsOwnContainerOverride返回`false`,那么模板似乎在项容器上设置. (2认同)