2016-02-05 177 views
7

我想使用ExpandoObject中的數據添加一行,這與Dictionary<string, object>類似。 string是該列的標題,object的值是該列的值。 每當我收到新數據時,我都會創建一個新的GridView,因爲列數可能不同。在List myItems都是行Dictionary<string, object>,我想在我的視圖中顯示。將列添加到包含圖像的列表視圖

這是我如何添加列到我的觀點:

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

直接在此之後我嘗試添加行:

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

我tryed修改此solution用於其他目的。這個解決方案工作得很好,如果我只想要添加的類型string的值,但現在我也想顯示在GridView的image,但如果我添加一個到我的GridView控件,它顯示我只是:

「System.Windows.Controls.Image」

現在我想知道,如果我可以修改我的代碼,這樣我可以顯示在GridView任何類型的(或至少imagesstrings)還是我使用完全新的方式,將是方式?

編輯:在以前的辦法,有人說,我需要創建一個新的DataTemplate顯示的圖像,但沒有解決方案(Solution 1Solution 2)我發現爲我工作。

+0

嘗試設置'鈰根據循環中創建列的數據類型,使用「llTemplate」作爲列。這是爲了防止一列總是顯示相同類型的數據。 如果數據的類型可能因行而改變,您可以添加'CellTemplateSelector',以便使用正確的模板。 – Shadowed

+0

我創建了一個新的'DataTemplate'並將'DataType'設置爲'typeof(Image)'。我必須設置更多屬性嗎?因爲我仍然得到相同的結果。 – daniel59

+0

我嘗試了這些解決方案來創建DataTemplate:http://stackoverflow.com/questions/248362/how-do-i-build-a-datatemplate-in-c-sharp-code和http://stackoverflow.com/questions/5471405/create-datatemplate-in-code-behind但它們都不適用於我。那麼如何創建一個在'gridview'中提供'images'的'DataTemplate'? – daniel59

回答

2

最好的方法是爲資源中的Icon列定義DataTemplate,然後在爲圖標創建列時加載它。我修改了您的代碼以顯示該方法。

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

    } 
} 

結果

enter image description here

+1

謝謝你的作品! – daniel59

1

我懷疑你可以在你使用的方法中使你的解決方案是通用的。它適用於具有適合您的有效ToString()表示的基於文本的數據類型。爲了處理像Images這樣複雜的數據類型,您可能必須使用Templates,因爲您需要爲每個複雜類型設置不同的屬性。例如對於圖像,它可能是大小和來源,對於按鈕 - 背景顏色。作爲選項,您可以創建某種模板工廠並應用CellTemplateSelector,這將爲您提供必要的模板,但正如您所說的那樣 - 它是一種全新的方式。