2016-02-05 145 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,这将为您提供必要的模板,但正如您所说的那样 - 它是一种全新的方式。