Lista condicional itemtemplate o datatemplate en WPF

Esta puede ser una pregunta obvia, pero creo que puede haber múltiples formas de implementarla, por lo que no solo me será útil, espero que sea útil para otros.

Básicamente, estoy buscando la mejor manera de implementar una vista de lista que pueda aceptar diferentes tipos de objetos y luego los represente con la plantilla de datos / elementos correspondiente para ese objeto.

Entonces, por ejemplo … tenemos una vista de lista de productos estándar, y cuando vemos diferentes categorías, la empresa ha decidido que le gustaría mostrar un estilo de plantilla de artículo diferente para cada categoría diferente.

La razón principal para preguntar esto aquí es evitar una desagradable solución pirata y descubrir un buen método de limpieza.

Espero haber proporcionado suficiente información, avíseme si necesita más.

Solo es suficiente con especificar las DataTemplates en los Resources con los respectivos DataType , por ejemplo

            

Captura de pantalla

(Tenga en cuenta que DataTemplate.DataType también se puede usar para plantillas de datos XML implícitos (ver documentos), el tipo de propiedad por ese motivo no es System.Type , así que a diferencia de Style.TargetType debe usar x:Type para hacer referencia a un CLR- tipo. Si solo ingresas una cadena, no se convertirá en un tipo).

También es posible que desee examinar CompositeCollections para obtener listas combinadas limpias de distintos tipos.


Datos de muestra que utilicé:

 ObservableCollection data = new ObservableCollection(new Employee[] { new Employee("Hans", "Programmer") , new Employee("Elister", "Programmer") , new Employee("Steve", "GUI Designer") , new Employee("Stephen", "GUI Designer") , new Employee("Joe", "Coffee Getter") , new Employee("Julien", "Programmer") , new Employee("John", "Coffee Getter") , }); ObservableCollection data2 = new ObservableCollection(new Machine[] { new Machine("XI2", String.Empty), new Machine("MK2-xx", String.Empty), new Machine("A2-B16", String.Empty), }); CompositeCollection cc1 = new CompositeCollection(); cc1.Add(new CollectionContainer() { Collection = data }); cc1.Add(new CollectionContainer() { Collection = data2 }); Data = cc1; 

Una opción es crear un DataTemplateSelector en tu código:

 public class QueueDisplayDataTemplateSelector : DataTemplateSelector { public override DataTemplate SelectTemplate(object item, System.Windows.DependencyObject container) { var listBoxItem = item as JobQueueListBoxItem; var resourceName = String.Empty; switch (listBoxItem.JobQueueListBoxItemType) { case JobQueueListBoxItemType.QueuedJob : resourceName = "DataTemplateQueuedJob"; break; case JobQueueListBoxItemType.TransferWorker : resourceName = "DataTemplateTransferWorker"; break; default: throw new InvalidOperationException(string.Format("There is no corresponding list box template for {0}", listBoxItem.JobQueueListBoxItemType)); } var element = container as FrameworkElement; return element.FindResource(resourceName) as DataTemplate; } } 

Esto luego sería declarado en su XAML como un recurso

    

Y luego le asignarías este cuadro de lista: