2010-08-03 19 views
10

Sono relativamente nuovo a WPF, e sembra che ci siano probabilmente un sacco di modi per farlo, ma non riesco a ottenere nessuno di quelli che ho provato a lavorare.Visualizza più tipi da un singolo elenco in un ListBox WPF?

Ho una ObservableCollection che contiene due tipi diversi.

Voglio associare questo elenco a un ListBox e visualizzare diversi DataTemplates per ogni tipo rilevato. Non riesco a capire come cambiare automaticamente i modelli di dati in base al tipo.

Ho tentato di utilizzare la proprietà DataType del DataTemplate e tentato uso ControlTemplate e un DataTrigger, ma senza alcun risultato, sia esso nulla si presenta, o si afferma che non riesce a trovare i miei tipi ...

Esempio Tentativo di seguito:

Ho solo il modello di dati collegato al ListBox in questo momento, ma anche quello non funziona.

XAML:

<Window x:Class="WpfApplication1.Window1" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
Title="Window1" Height="300" Width="300"> 
<Window.Resources> 
    <DataTemplate x:Key="PersonTemplate"> 
     <TextBlock Text="{Binding Path=Name}"></TextBlock> 
    </DataTemplate> 

    <DataTemplate x:Key="QuantityTemplate"> 
     <TextBlock Text="{Binding Path=Amount}"></TextBlock> 
    </DataTemplate> 

</Window.Resources> 
<Grid> 
    <DockPanel> 
     <ListBox x:Name="MyListBox" Width="250" Height="250" 
ItemsSource="{Binding Path=ListToBind}" 
ItemTemplate="{StaticResource PersonTemplate}"></ListBox> 
    </DockPanel> 
</Grid> 
</Window> 

Codice Dietro:

public class Person 
{ 
    public string Name { get; set; } 

    public Person(string name) 
    { 
     Name = name; 
    } 
} 

public class Quantity 
{ 
    public int Amount { get; set; } 

    public Quantity(int amount) 
    { 
     Amount = amount; 
    } 
} 

public partial class Window1 : Window 
{ 
    ObservableCollection<object> ListToBind = new ObservableCollection<object>(); 

    public Window1() 
    { 
     InitializeComponent(); 

     ListToBind.Add(new Person("Name1")); 
     ListToBind.Add(new Person("Name2")); 
     ListToBind.Add(new Quantity(123)); 
     ListToBind.Add(new Person("Name3")); 
     ListToBind.Add(new Person("Name4")); 
     ListToBind.Add(new Quantity(456)); 
     ListToBind.Add(new Person("Name5")); 
     ListToBind.Add(new Quantity(789)); 
    } 
} 

risposta

6

Lei dice che "sostiene che non riesce a trovare i miei tipi." Questo è un problema che dovresti risolvere.

Il problema, molto probabilmente, è che non si sta creando una dichiarazione dello spazio dei nomi in XAML che fa riferimento allo spazio dei nomi e all'assembly CLR. Hai bisogno di mettere qualcosa di simile in elemento di livello del XAML:

xmlns:foo="clr-namespace:MyNamespaceName;assembly=MyAssemblyName" 

Una volta fatto questo, XAML saprà che qualsiasi cosa con il namespace prefix XML foo è in realtà una classe in MyAssemblyName nel MyNamespaceName namespace.

Quindi è possibile fare riferimento a quel namespace XML nel codice che ha creato il DataTemplate:

<DataTemplate DataType="{foo:Person}"> 

Si può certamente costruire un selettore di modello, ma questo è l'aggiunta di un pezzo di cruft al software che non ha bisogno di essere lì C'è un posto per i selettori di modelli nelle applicazioni WPF, ma non è questo.

+2

+1 Hai ragione. Mi chiedo perché non ho mai visto questa fantastica opzione. Qui il msdn-link: http://msdn.microsoft.com/en-us/library/system.windows.datatemplate.datatype.aspx – HCL

+0

Il DataTemplateSelector sembra cruft una volta inserito. Grazie per il suggerimento. Ho pensato che ci fosse un modo semplice per risolvere questo problema, e tu l'hai fornito! – davisoa

+1

non funziona per me, ma fa. Errore di battitura? –

6

Devi usare un DataTemplateSelector. Vedi here per un esempio.

informazioni Addiontal su MSDN

+0

Che funziona come un fascino! Grazie! – davisoa

+1

Non è necessario utilizzare un selettore di modelli; Il metodo di selezione del modello predefinito di WPF fa esattamente ciò che è necessario qui. –