2010-05-01 3 views
7

Я создаю пользовательский элемент управления WPF, который происходит из TabControl. В ControlTemplate я использую ItemControl для отображения списка, связанного с шаблоном (наблюдаемая коллекция типа FileMenuItem). Во время выполнения программы, я получаю следующее сообщение об ошибке в окне вывода:WPF Custom Control - ItemsControl template не применяется

ItemTemplate и ItemTemplateSelector игнорируется для элементов уже контейнерного типа в ItemsControl в; Тип = '' FileMenuItem

Тип FileMenuItem является производным от MenuItem. Если я изменил базовый класс на DependencyObject, код действительно запускается и применяется шаблон (так что это опция). Я googled ошибка и ничего не мог найти об этом, кто-нибудь сталкивается с этим при разработке пользовательских элементов управления? Несмотря на то, что у меня есть обходной путь, я хотел бы понять, что происходит, и я думаю, что использование MenuItem в качестве базового класса - более чистая реализация.

Я могу разместить больше кода, если это поможет. Благодаря!

ответ

6

Цель DataTemplate (например, ItemTemplate) - предоставить визуализацию для объекта данных. В частности, он определяет набор элементов для добавления в визуальное дерево вместо данных, предоставленных ContentPresenter или ItemsPresenter. В вашем случае ваш исходный список представляет собой набор объектов, которые уже могут быть добавлены непосредственно в визуальное дерево для отображения в пользовательском интерфейсе.

Вы можете увидеть это в следующем упрощенном примере, где в красном отобразится только «Три», потому что первые два элемента определены в форме, которая может отображаться непосредственно ComboBox.

<ComboBox> 
    <ComboBox.ItemTemplate> 
     <DataTemplate> 
      <TextBlock Text="{Binding}" Foreground="Red"/> 
     </DataTemplate> 
    </ComboBox.ItemTemplate> 
    <ComboBoxItem>One</ComboBoxItem> 
    <ComboBoxItem>Two</ComboBoxItem> 
    <sys:String>Three</sys:String> 
</ComboBox> 
+1

ОК, я думаю, что понимаю - так, возможно ли поддерживать этот сценарий или мне нужно переключиться на наследование из другого базового класса? Спасибо за вашу помощь! –

+5

Есть много разных способов, которыми вы могли бы пойти. Вы должны попытаться решить, хотите ли вы обрабатывать элементы коллекции как элементы управления (полученные из UIElement) или данные (INotifyPropertyChanged или DependencyObject) или создавать как класс данных, так и элемент управления пользовательского интерфейса или DataTemplate. Другой возможный вариант - это производный элемент ItemsControl, который переопределяет GetContainerForItemOverride и IsItemItsOwnContainerOverride для использования контейнера FileMenuItem для каждого элемента (ComboBox, ListBox и т. Д.). –

+5

Один из самых простых (и эффективных) подходов к решению этой проблемы для меня всегда заключался в том, чтобы получить свой собственный элемент ItemsControl и переопределить метод IsItemItsOwnContainerOverride для возврата false, что означает, что DataTemplate не будет пропущен из-за проблемы John объяснил. – GEEF