12

我可以在 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>

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

4

2 回答 2

18

有一个受保护的ItemsControl成员IsItemItsOwnContainerOverride,它从项目集合中传递一个对象,true如果该对象可以在没有生成容器的情况下直接添加到项目面板(并因此被模板化),则返回。

对于派生自 的任何对象,基本实现都返回 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;
    }
于 2010-10-02T07:34:53.300 回答
2

我只是在这里推测,但我敢打赌这是生活在ItemContainerGenerator. 我敢打赌,ItemContainerGenerator如果它是一个项目,UIElement它会说,“酷,项目容器已经生成,我会返回它”,如果不是,它说,“我最好生成一个容器对于这个项目。在哪里DataTemplate

于 2010-10-02T00:46:43.827 回答