2010-05-01 13 views
7

Buduję niestandardowy formant WPF, który wywodzi się z TabControl. W ControlTemplate używam ItemsControl, aby wyświetlić listę, która jest związana z szablonem (obserwowalna kolekcja typu FileMenuItem). Podczas wykonywania programu, otrzymuję następujący błąd w oknie wyjściowym:Niestandardowe sterowanie WPF - szablon ItemsControl nie jest stosowany

ItemTemplate i ItemTemplateSelector są ignorowane przedmiotów już Spośród ItemsControl typ kontenera; Typ = 'FileMenuItem'

Typ FileMenuItem pochodzi z MenuItem. Jeśli zmienię klasę podstawową na DependencyObject, kod faktycznie działa i szablon zostanie zastosowany (więc jest to opcja). Przeszukałem ten błąd i nie mogłem znaleźć nic na ten temat, czy ktokolwiek wpadł na to podczas opracowywania niestandardowych elementów sterujących? Chociaż mam obejście, chciałbym zrozumieć, co się dzieje, i myślę, że używanie MenuItem jako klasy bazowej jest czystszą implementacją.

Mogę opublikować więcej kodu, jeśli mogłoby to pomóc. Dzięki!

Odpowiedz

6

Celem DataTemplate (podobnie jak ItemTemplate) jest zapewnienie wizualizacji obiektu danych. W szczególności definiuje zestaw elementów do dodania do drzewa wizualnego w miejsce danych przekazanych do ContentPresenter lub ItemsPresenter. W twoim przypadku twoja lista źródłowa to zbiór obiektów, które można już dodać bezpośrednio do drzewa wizualnego do wyświetlenia w interfejsie użytkownika.

Można to zobaczyć w poniższym uproszczonym przykładzie, w którym tylko "Trzy" pojawia się na czerwono, ponieważ pierwsze dwa elementy są zdefiniowane w formie, która może być wyświetlana bezpośrednio przez 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

OK, myślę, że rozumiem - czy możliwe jest wsparcie tego scenariusza, czy muszę przełączyć się na dziedziczenie z innej klasy bazowej? Dzięki za pomoc! –

+5

Istnieje wiele różnych sposobów, w jakie możesz pójść. Powinieneś podjąć decyzję, czy chcesz traktować elementy kolekcji jako kontrole (pochodzące z UIElement) lub dane (INotifyPropertyChanged lub DependencyObject), czy też utworzyć zarówno klasę danych, jak i kontrolkę interfejsu użytkownika lub DataTemplate. Inną możliwą opcją jest wyprowadzona ItemsControl, która zastępuje GetContainerForItemOverride i IsItemItsOwnContainerOverride w celu użycia kontenera FileMenuItem dla każdego elementu (ComboBox, ListBox, itp.). –

+5

Jednym z najprostszych (i skutecznych) sposobów rozwiązania tego problemu był dla mnie zawsze wyprowadzenie własnego ItemsControl i nadpisanie metody 'IsItemItsOwnContainerOverride' w celu zwrócenia false, co oznacza, że ​​DataTemplate nie zostanie pominięty z powodu problemu z Johnem wyjaśnione. – GEEF

Powiązane problemy