2009-02-24 8 views
5

Konnte keine Antwort zu diesem finden.WPF - Set DataTemplate für programmgesteuert hinzugefügt GridViewColumns

Ich habe ein WPF ListView-Steuerelement, das unterschiedliche Anzahl von Spalten enthalten kann. Zum Beispiel kann es Kundendaten anzeigen, Spalten ID, Name, E-Mail usw. anzeigen, oder es kann Produkte enthalten ID, Name, Preis, NumberInStock, Hersteller, naja, Sie bekommen die Idee: unterschiedliche Anzahl von Spalten, unterschiedliche Namen.

Was ich tun möchte, ist für bestimmte Spalten, die Daten unterschiedlich anzuzeigen. Anstatt beispielsweise "Yes" oder "No" als Wert der Spalte NumberInStock zu drucken, möchte ich ein sauberes Bild anzeigen.

Wenn ich eine feste Anzahl von Spalten hätte, mit festen Namen zu binden, sehe ich irgendwie, wie das einfach ist. Definieren Sie einfach ein DataTemplate für diese bestimmte Spalte, und ich würde das verwenden, um die Ansicht meiner Spalte zu definieren. Ich kann jedoch nicht sehen, wie ich es in meiner Situation mache.

Ich bin sehr neu in WPF, also entschuldige mich, wenn mein Ansatz schlecht ist :-) In meinem XAML habe ich ein ListView-Steuerelement definiert, das ziemlich leer ist. In meinem Code hinter, ich benutze:

// get all columns from my objects (which can be either a Customer of Product) 
    foreach (string columnName in MyObject.Columns) 
     { 
      GridViewColumn column = new GridViewColumn(); 
      // Bind to a property of my object 
      column.DisplayMemberBinding = new Binding("MyObject." + columnName); 
      column.Header = columnName; 
      column.Width = 50; 
      // If the columnname is number of stock, set the template to a specific datatemplate defined in XAML 
      if (columnName == "NumberInStock") 
      column.CellTemplate = (DataTemplate)FindResource("numberInStockImageTemplate"); 
      explorerGrid.Columns.Add(column); 
     } 

Ok, ich bin sicher, dass dies ein wenig schönere getan werden könnte (wenn Sie einen Rat haben, bitte!), Aber das größte Problem ist, dass ich nicht sehen kann Unterschied in der Spalte. Es zeigt nur den Textwert der Spalte 'NumberInStock' an. Mein Datatemplate ist in der XAML definiert:

<Window.Resources> 
<DataTemplate x:Name="NumberInStock" x:Key="NumberInStock"> 
     <Border BorderBrush="Red" BorderThickness="2.0"> 
     <DockPanel> 
      <Image Width="24" Height="24" Margin="3,0" Source="..\Images\instock.png" /> 
     </DockPanel> 
     </Border> 
</DataTemplate> 
</Window.Resources> 

Natürlich würde ich noch die Funktionalität hinzufügen muß, dass es ein ‚Ja‘ oder ‚Nein‘ Bild je nach dem Wert von NumberInStock angezeigt werden würde, aber das ist Schritt 2 wirklich. Ich würde mich freuen, ein Bild und einen roten Rand in meinem ListView zu sehen!

Vielen Dank im Voraus, Razzie

Antwort

7

Dies stolperte mich für eine Weile.

DisplayMemberBinding und CellTemplate schließen sich gegenseitig aus. Bei Angabe einer DisplayMemberBinding wird die CellTemplate ignoriert.

Von MSDN:

Die folgenden Eigenschaften werden verwendet, den Inhalt und Stil einer Spalte Zelle zu definieren, und sind in der Rangfolge aufgelistet, von höchsten zum niedrigsten:

* DisplayMemberBinding 
* CellTemplate 
* CellTemplateSelector 

auch eine C# Disciples post darüber sehen.

+0

Danke, das sieht tatsächlich nach dem Problem aus. Ich habe meinen Code bereits bearbeitet, um ein DataGrid-Steuerelement zu verwenden, das mit SP1 geliefert wird. Es mag sowieso besser in meiner Situation sein. Aber das ist definitiv die richtige Lösung. Danke vielmals! – Razzie

0

Ich denke, das Problem ist, dass die Zeichenfolge, die Sie FindResource() vorbei sind nicht der Schlüssel der Ressource, die Sie in der XAML definiert entspricht. Versuche stattdessen "NumberInStock" zu passieren und schau, ob das funktioniert.

+0

Sharp einfügen! Leider war es nur ein Kopier-Paste-Edit-für-Frage-Fehler auf meiner Seite.Es zeigt auf den richtigen Schlüssel in meinem Code. Darüber hinaus löst FindResource (string) eine Ausnahme aus, wenn der Schlüssel nicht gefunden wird. Danke trotzdem! – Razzie

2

das ist der einfachste Weg, ein Bild

 GridViewColumn column = new GridViewColumn { Header = "IM" };    
     DataTemplate template = new DataTemplate(); 

     FrameworkElementFactory factory = new FrameworkElementFactory(typeof(Grid)); 
     template.VisualTree = factory; 
     FrameworkElementFactory imgFactory = new FrameworkElementFactory(typeof(Image)); 

     Binding newBinding = new Binding("IMG"); 
     imgFactory.SetBinding(Image.SourceProperty,newBinding); 
     imgFactory.SetValue(Image.WidthProperty,15.0); 
     imgFactory.SetValue(Image.HeightProperty, 15.0); 

     factory.AppendChild(imgFactory); 
     column.CellTemplate = template; 
     view.Columns.Add(column); 

     ListViewMain.View = view; 

+0

Etwas mehr Erklärung wäre nützlich, aber das führte mich zur richtigen Antwort (zu meinem Fall). Kurz gesagt: _Dies erzeugt den Inhaltsersteller für eine Spalte, also wird jede Zeile der Factory aufgerufen, um in der Factory definierte Steuerelemente zu erzeugen. _ Danke .. +1 –

+0

Dieser Stil funktionierte für mich. HINWEIS: Meine Bindung war an eine Eigenschaft einer untergeordneten Objekteigenschaft, also sah sie so aus: 'Binding newBinding = new Binding (" ChildProp.SubProp "); newBinding.Converter = new MyConverter(); ' –