2016-02-05 39 views
7

Chcę dodać wiersz przy użyciu danych z ExpandoObject, który jest podobny do Dictionary<string, object>. string jest nagłówkiem kolumny, a wartość object jest wartością kolumny. Za każdym razem, gdy otrzymuję nowe dane, tworzę nowy GridView, ponieważ liczba kolumn może być inna. W List myItems są wszystkie wiersze Dictionary<string, object>, które chcę pokazać w moim widoku.Dodaj kolumnę do listy zawierającej obraz

ten sposób mogę dodać kolumny do mojego widoku:

  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 }); 
       } 
      } 

bezpośrednie po tym staram się dodać wiersze:

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

tryed zmodyfikować ten solution dla innych celów. To rozwiązanie działa bardzo dobrze, jeśli tylko chcesz dodać wartości typu string, ale teraz chcę też wyświetlać image w GridView, ale jeśli dodasz do mojego GridView, to pokazuje mi tylko:

„System.Windows.Controls.Image”

teraz chcę wiedzieć, czy mogę zmodyfikować mojego kodu, tak mogę wyświetlić dowolny typ (lub co najmniej images i strings) w gridview czy muszę korzystać z zupełnie nowej drogi i byłby sposób?

EDIT: W poprzednich podejść, mówiło się, że trzeba stworzyć nową DataTemplate aby wyświetlić obrazek, ale żadne z rozwiązań (Solution 1, Solution 2) znalazłem pracuje dla mnie.

+0

Spróbuj ustawić 'Ce lLTemplate' dla kolumny opartej na typie danych w pętli, w której tworzysz kolumny. Jest tak na wypadek, gdyby jedna kolumna zawsze pokazywała ten sam typ danych. Jeśli typ danych może zmienić się z wiersza na wiersz, można dodać 'CellTemplateSelector', aby użyć odpowiedniego szablonu. – Shadowed

+0

Stworzyłem nowy 'DataTemplate' i ustawiłem' DataType' na 'typeof (Image)'. Czy muszę ustawić więcej właściwości? ponieważ wciąż otrzymuję ten sam rezultat. – daniel59

+0

Wypróbowałem te rozwiązania, aby utworzyć DataTemplate: http://stackoverflow.com/questions/248362/how-do-i-builda-a-datatemplate-in-c-sharpcode i http://stackoverflow.com/questions/5471405/create-datatemplate-in-code-behind, ale żaden z nich nie działa dla mnie. Więc jak mogę utworzyć 'DataTemplate', który zapewnia' obrazy' w 'gridview'? – daniel59

Odpowiedz

2

Najlepszym sposobem jest zdefiniowanie DataTemplate dla kolumny Ikona w zasobach, a następnie załadowanie jej podczas tworzenia kolumny dla ikony. Zmodyfikowałem twój kod, aby pokazać podejście.

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); 
     } 

    } 
} 

Wyniki

enter image description here

+1

Dziękuję, to działa! – daniel59

1

Wątpię, czy będziesz w stanie zrobić ogólne rozwiązanie w ramach podejścia, z którego korzystasz. Działa dobrze dla tekstowych typów danych, które mają poprawną reprezentację ToString(), która pasuje do ciebie. W przypadku pracy ze złożonym typem danych, takim jak Obrazy, prawdopodobnie będziesz musiał użyć Templates, jak zacytował Shadowed, gdzie będziesz musiał ustawić różne właściwości dla każdego typu złożonego. Na przykład dla obrazu może to być rozmiar i źródło dla przycisku - kolor tła. Opcjonalnie możesz utworzyć fabrykę szablonów i zastosować szablon CellTemplateSelector, który zapewni Ci szablony niewymagane, ale tak jak powiedziałeś - jest to zupełnie nowy sposób.