2016-02-05 32 views
7

Desidero aggiungere una riga utilizzando i dati da ExpandoObject, che è simile a Dictionary<string, object>. Il string è l'intestazione della colonna e il valore di object è il valore della colonna. Ogni volta che ottengo nuovi dati sto creando un nuovo GridView, perché il numero di colonne può essere diverso. Nel List myItems sono tutte le righe Dictionary<string, object>, che voglio mostrare a mio avviso.Aggiungi colonna a listview che contiene un'immagine

Questo è quanto ho aggiungere le colonne al mio punto di vista:

  List<Column> columns = new List<Column>(); 

      myItemValues = (IDictionary<string, object>)myItems[0]; 
      // Key is the column, value is the value 
      foreach (var pair in myItemValues) 
      { 
       Column column = new Column(); 
       column.Title = pair.Key; 
       column.SourceField = pair.Key; 
       columns.Add(column); 
      } 
      view.Columns.Clear(); 
      foreach (var column in columns) 
      { 
       Binding binding = new Binding(column.SourceField); 
       if (column.SourceField == "Icon") 
       { 
        view.Columns.Add(new GridViewColumn 
        { 
         Header = column.Title, 
         DisplayMemberBinding = binding, 
         CellTemplate = new DataTemplate(typeof(Image)) 
        }); 
       } 
       else 
       { 
        view.Columns.Add(new GridViewColumn { Header = column.Title, DisplayMemberBinding = binding }); 
       } 
      } 

diretto dopo questo cerco di aggiungere le righe:

  foreach (dynamic item in myItems) 
      { 
       this.listView.Items.Add(item); 
      } 

Ho provato a modificare questo solution per un altro scopo. Questa soluzione funziona molto bene, se solo voglio aggiungere valori di tipo string, ma ora voglio anche visualizzare un image nella GridView, ma se aggiungo uno al mio GridView, mi mostra solo:

"System.Windows.Controls.Image"

Ora voglio sapere, se posso modificare il mio codice in modo da posso visualizzare qualsiasi tipo (o almeno images e strings) in una gridView o devo usare un modo completamente nuovo e sarebbe il modo?

EDIT: Nei precedenti approcci, si è detto, che ho bisogno di creare un nuovo DataTemplate per mostrare un'immagine, ma nessuna delle soluzioni (Solution 1, Solution 2) ho trovato sta lavorando per me.

+0

provare a impostare 'Ce llTemplate' per la colonna in base al tipo di dati in loop in cui si creano colonne. Questo è nel caso in cui una colonna mostri sempre lo stesso tipo di dati. Se il tipo di dati può cambiare da una riga all'altra, è possibile aggiungere 'CellTemplateSelector' in modo che venga utilizzato il modello corretto. – Shadowed

+0

Ho creato un nuovo 'DataTemplate' e ho impostato' DataType' su 'typeof (Image)'. Devo impostare più proprietà? perché ho ancora lo stesso risultato. – daniel59

+0

Ho provato queste soluzioni per creare un DataTemplate: http://stackoverflow.com/questions/248362/how-do-i-build-a-datatemplate-in-c-sharp-code e http://stackoverflow.com/questions/5471405/create-datatemplate-in-code-behind ma nessuno di loro funziona per me. Quindi, come posso creare un 'DataTemplate' che fornisce' images' in un 'gridview'? – daniel59

risposta

2

Il modo migliore è definire DataTemplate per la colonna Icona in risorse, quindi caricarlo quando si crea la colonna per l'icona. Ho modificato il tuo codice per mostrare l'approccio.

XAML

<Window x:Class="ListViewIcon.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:local="clr-namespace:ListViewIcon" 
     mc:Ignorable="d" 
     Title="MainWindow" Height="350" Width="525"> 
    <Window.Resources> 
     <ResourceDictionary> 
      <DataTemplate x:Key="iconTemplate"> 
       <Image Source="{Binding Icon}" 
        Width="64" 
        Height="64"/> 
      </DataTemplate> 
     </ResourceDictionary> 
    </Window.Resources> 
    <Grid> 
     <ListView x:Name="myListView"></ListView> 

    </Grid> 
</Window> 

C#

public class Column 
{ 
    public string Title { get; set; } 
    public string SourceField { get; set; } 
} 

public partial class MainWindow : Window 
{ 
    private BitmapImage LoadImage() 
    { 
     var img = new BitmapImage(); 
     img.BeginInit(); 
     img.UriSource = new Uri(@"D:\image.png", UriKind.Absolute); 
     img.CacheOption = BitmapCacheOption.OnLoad; 
     img.EndInit(); 

     return img; 
    } 

    public MainWindow() 
    { 
     InitializeComponent(); 

     GridView gridView = new GridView(); 
     this.myListView.View = gridView; 

     List<dynamic> myItems = new List<dynamic>(); 
     dynamic myItem; 
     IDictionary<string, object> myItemValues; 

     var image = LoadImage(); 

     // Populate the objects with dynamic columns 
     for (var i = 0; i < 100; i++) 
     { 
      myItem = new System.Dynamic.ExpandoObject(); 

      foreach (string column in new string[] { "Id", "Name", "Something" }) 
      { 
       myItemValues = (IDictionary<string, object>)myItem; 
       myItemValues[column] = "My value for " + column + " - " + i; 
      } 

      myItem.Icon = image; 

      myItems.Add(myItem); 
     } 

     // Assuming that all objects have same columns - using first item to determine the columns 
     List<Column> columns = new List<Column>(); 

     myItemValues = (IDictionary<string, object>)myItems[0]; 

     // Key is the column, value is the value 
     foreach (var pair in myItemValues) 
     { 
      Column column = new Column(); 

      column.Title = pair.Key; 
      column.SourceField = pair.Key; 

      columns.Add(column); 
     } 

     // Add the column definitions to the list view 
     gridView.Columns.Clear(); 

     foreach (var column in columns) 
     { 

      if (column.SourceField == "Icon") 
      { 
       gridView.Columns.Add(new GridViewColumn 
       { 
        Header = column.Title, 
        CellTemplate = FindResource("iconTemplate") as DataTemplate 
       }); 
      } 
      else 
      { 
       var binding = new Binding(column.SourceField); 
       gridView.Columns.Add(new GridViewColumn { Header = column.Title, DisplayMemberBinding = binding }); 
      } 


     } 

     // Add all items to the list 
     foreach (dynamic item in myItems) 
     { 
      this.myListView.Items.Add(item); 
     } 

    } 
} 

Risultati

enter image description here

+1

Grazie, funziona! – daniel59

1

Dubito che sarete in grado di rendere la vostra soluzione generica con l'approccio che state utilizzando. Funziona bene per i tipi di dati basati su testo che hanno una rappresentazione ToString() valida, che fa per te. Per lavorare con il tipo di dati complesso come Immagini, probabilmente dovrai usare Templates, come indicato da Shadowed, dove dovrai configurare proprietà differenti per ogni tipo complesso. Ad esempio per l'immagine potrebbe essere la dimensione e la fonte, per il pulsante - il colore di sfondo. Come opzione, puoi creare una sorta di modello di fabbrica e applicare lo CellTemplateSelector, che ti fornirà i modelli necessari, ma è, come hai detto tu, che è un modo completamente nuovo.