2009-02-24 14 views
5

Impossibile trovare una risposta a questo.WPF - Imposta DataTemplate per GridViewColumns aggiunto al livello di programmazione

Ho un controllo ListView WPF che può contenere un numero variabile di colonne. Ad esempio, può visualizzare i dati dei clienti, visualizzando colonne Id, Nome, Email ecc, oppure può contenere prodotti, visualizzando ID, Nome, Prezzo, NumeroInchiostro, Produttore, beh, si ottiene l'idea: numero variabile di colonne, nomi diversi.

Quello che voglio fare è che alcune colonne visualizzino i dati in modo diverso. Ad esempio, invece di stampare "Sì" o "No" come valore della colonna NumberInStock, voglio visualizzare un'immagine nitida.

Se avessi una quantità fissa di colonne, con nomi fissi da associare, vedo un po 'com'è facile. Basta definire un DataTemplate per quella particolare colonna e lo userei per definire la vista della mia colonna. Tuttavia, non riesco a vedere come farlo nella mia situazione.

Sono molto nuovo a WPF, quindi scusami se il mio approccio è sbagliato :-) Nel mio XAML, ho definito un controllo ListView, che è praticamente vuoto. Nel mio codice dietro, io uso:

// 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, sono sicuro che questo potrebbe essere fatto un po 'più carina (se avete qualche consiglio, per favore!), Ma il problema più grande è che non riesco a vedere alcun differenza nella colonna. Visualizza solo il valore del testo della colonna 'NumberInStock'. Il mio DataTemplate viene definito nel XAML:

<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> 

Naturalmente, avrei ancora per aggiungere la funzionalità che sarebbe visualizzare un 'sì' o 'no' immagine a seconda del valore della NumberInStock, ma questo è il passo 2 davvero. Sarei felice di vedere un'immagine e un bordo rosso nel mio ListView!

Grazie in anticipo, Razzie

risposta

7

Questo mi ha fatto inciampare per un po '.

DisplayMemberBinding e CellTemplate si escludono a vicenda. La specifica di DisplayMemberBinding fa sì che lo CellTemplate venga ignorato.

Da MSDN:

Le seguenti proprietà sono tutti utilizzati per definire il contenuto e lo stile di una cella colonna e sono elencati qui in loro ordine di precedenza, da più alto al più basso:

* DisplayMemberBinding 
* CellTemplate 
* CellTemplateSelector 

vedere anche un C# Disciples post su questo.

+0

Grazie, sembra davvero il problema. Ho già modificato il mio codice per utilizzare un controllo DataGrid fornito con SP1. Potrebbe essere più adatto comunque nella mia situazione. Ma questa è sicuramente la soluzione giusta. Grazie molto! – Razzie

0

Credo che il problema è che la stringa che si sta passando a FindResource() non corrisponde alla chiave della risorsa che si è definito nel XAML. Prova a passare "NumberInStock" invece e vedere se funziona.

+0

Sharp! Sfortunatamente, è stato solo un errore copy-paste-edit-for-question dalla mia parte.Punta alla chiave corretta nel mio codice. Inoltre, FindResource (stringa) genera un'eccezione quando la chiave non viene trovata. Grazie comunque! – Razzie

2

questo è il modo più semplice per inserire un'immagine

 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

Qualche altra spiegazione sarebbe utile, ma questo mi porta alla risposta giusta (sul mio caso). In poche parole: _Questo genererà il creatore di contenuti per una colonna, quindi ogni riga viene chiamata la fabbrica per generare i controlli definiti in fabbrica._ grazie .. +1 –

+0

Questo stile ha funzionato per me. NOTA: il mio binding era una proprietà di una proprietà dell'oggetto figlio, quindi assomigliava a questo: 'Binding newBinding = new Binding (" ChildProp.SubProp "); newBinding.Converter = new MyConverter(); ' –

Problemi correlati