2011-03-29 10 views
19

¿es posible vincular un control de elementos con canvas como plantilla a múltiples DataTemplates?ItemsControl con múltiples DataTemplates para un modelo de vista

Tengo 2 colecciones y, dependiendo del tipo, me gustaría mostrar un control diferente sobre mi lienzo.

No estoy seguro, pero podría pensar en un Viewmodel que tenga 2 ObservableCollections. Por ejemplo, si tuviera "Formas" y "conexiones" y me gustaría mostrarlas en el lienzo. En caso de un escenario de diagramación ...

Me gustaría hacer esto de la manera mvvm y no estoy seguro de si el enfoque múltiple de DataTemplate es correcto, pero se me vino a la mente. Pero sigo teniendo problemas para obtener el encuadernador directamente en mi cabeza. Si configuro DataContext para ViewModel para mí, no parece posible enlazar 2 colecciones al control de elementos ... = ( También estoy abierto para otras ideas, también ...

¿Es esto posible? Si es así, ¿cómo sería el aspecto de unión como un

+0

¿Lo necesita ** AMBOS ** para WPF y Silverlight? – Snowbear

+0

ambos serían buenos a largo plazo ... pero primero WPF sería genial ... – silverfighter

+0

DataTemplateSelector funcionará para 'WPF' y' Silverlight'. – vorrtex

Respuesta

41

Puede crear múltiples ObservableCollections y luego enlazar su ItemsSource a CompositeCollection que se une a esas colecciones.

Luego, en su XAML puede crear diferentes DataTemplates para los tipos respectivos usando la propiedad DataType, que le gusta aplicar estilos automáticamente si se coloca en los recursos. (También se puede crear el material compuesto en XAML que se muestra en MSDN, si el CollectionContainers debe estar sujeta a que es a bit more difficult aunque) código

Ejemplo:

ObservableCollection<Employee> data1 = new ObservableCollection<Employee>(new Employee[] 
{ 
    new Employee("Hans", "Programmer"), 
    new Employee("Elister", "Programmer"), 
    new Employee("Steve", "GUI Designer"), 
    new Employee("Stefan", "GUI Designer"), 
    new Employee("Joe", "Coffee Getter"), 
    new Employee("Julien", "Programmer"), 
}); 
ObservableCollection<Machine> data2 = new ObservableCollection<Machine>(new Machine[] 
{ 
    new Machine("E12", "GreedCorp"), 
    new Machine("E11", "GreedCorp"), 
    new Machine("F1-MII", "CommerceComp"), 
    new Machine("F2-E5", "CommerceComp") 
}); 
CompositeCollection coll = new CompositeCollection(); 
coll.Add(new CollectionContainer() { Collection = data1 }); 
coll.Add(new CollectionContainer() { Collection = data2 }); 
Data = coll; 
<ItemsControl ItemsSource="{Binding Data}"> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <VirtualizingStackPanel/> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
    <ItemsControl.Resources> 
     <DataTemplate DataType="{x:Type local:Employee}"> 
      <StackPanel Orientation="Horizontal"> 
       <TextBlock Text="{Binding Name}"/> 
       <TextBlock Text=" ("/> 
       <TextBlock Text="{Binding Occupation}"/> 
       <TextBlock Text=")"/> 
      </StackPanel> 
     </DataTemplate> 
     <DataTemplate DataType="{x:Type local:Machine}"> 
      <StackPanel Orientation="Horizontal"> 
       <TextBlock Text="{Binding Model}"/> 
       <TextBlock Text=" - "/> 
       <TextBlock Text="{Binding Manufacturer}"/> 
      </StackPanel> 
     </DataTemplate> 
    </ItemsControl.Resources> 
</ItemsControl> 

Aquí utilizo un diferente panel, pero debería ser lo mismo para un lienzo.

+0

gracias, no sabía sobre compositecollection ... – silverfighter

5

Usted podría tener ObservableCollection<object> en su modelo de vista y se unen Fuente de ItemsControl a esta colección

Th es, para obtener un aspecto diferente para los diferentes tipos de datos, puede dos plantillas de datos sin x: clave, pero con el tipo de datos establecido correctamente en sus recursos. El ItemsControl seleccionará automáticamente el DataTemplate apropiado para su artículo.

-4

Otra opción con menos código detrás sería definir dos ListBoxes, cada uno con sus propias plantillas y vinculados a sus propias colecciones. Defínalos en el mismo espacio físico y simplemente controle cuál es visible en función de su estado. Incluso podría hacer esto con el Visual State Manager y los estados personalizados.

Cuestiones relacionadas