Почему ItemsControl Не Использует Мой ItemTemplate?
Я могу использовать ItemTemplate в ItemsControl для отображения элементов в определенном формате. Однако, если один из элементов в ItemsControl является, скажем, текстовым полем, это текстовое поле отображается, а не экземпляр 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 определен, каждый элемент в коллекции отображается как экземпляр шаблона. Однако в этом случае отображается следующее: синий прямоугольник, за которым следует текстовое поле, затем синий прямоугольник, за которым следует красный прямоугольник.
2 ответов
на ItemsControl
имеет защищенный который передается объект из коллекции items и возвращает true
если этот объект может быть добавлен непосредственно на панель элементов без сгенерированного контейнера (и, следовательно, быть шаблоном).
базовая реализация возвращает true для любого объекта, производного от UIElement
.
чтобы получить поведение, которое вы ожидаете, вам нужно будет унаследовать от ItemsControl
и переопределить этот метод и всегда возвращать false. К сожалению, это еще не все. Реализация по умолчанию 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;
}
Я просто спекулирую здесь, но я бы поспорил, что это поведение, которое живет внутри ItemContainerGenerator
. Держу пари, что ItemContainerGenerator
смотрит на элемент, и если это UIElement
Он говорит:" круто, контейнер элемента был сгенерирован, я просто верну его", и если это не так, он говорит: "мне лучше сгенерировать контейнер для этого элемента. Где DataTemplate
?"