如何在WPF DataGrid中动态生成列? [英] How do I dynamically generate columns in a WPF DataGrid?

查看:1988
本文介绍了如何在WPF DataGrid中动态生成列?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在WPF数据网格中显示一个查询的结果。我绑定的ItemsSource类型是 IEnumerable< dynamic> 。由于返回的字段在运行时没有确定,因此在查询被评估之前,我不知道数据的类型。每个行作为 ExpandoObject 返回,其中包含表示字段的动态属性。



我希望 AutoGenerateColumns (如下所示)将能够从 ExpandoObject 生成列,就像静态类型一样,但它不

 < DataGrid AutoGenerateColumns =TrueItemsSource ={Binding Results}/> 

有没有声明地做这个或者我必须用一些C# p>

编辑



确定这会让我找到正确的列:

  // ExpandoObject实现IDictionary< string,object> 
IEnumerable< IDictionary< string,object>> rows = dataGrid1.ItemsSource.OfType< IDictionary< string,object>>();
IEnumerable< string> columns = rows.SelectMany(d => d.Keys).Distinct(StringComparer.OrdinalIgnoreCase);
foreach(列中的字符串)
dataGrid1.Columns.Add(new DataGridTextColumn {Header = s});

所以现在只需要弄清楚如何将列绑定到IDictionary值。

解决方案

最终我需要做两件事:


  1. 从查询返回的属性列表中手动生成列

  2. 设置DataBinding对象

之后,内置的数据绑定踢入并正常工作,似乎没有任何问题,从 ExpandoObject 中获取属性值。

 < DataGrid AutoGenerateColumns =FalseItemsSource ={Binding Results}/> 

  //由于不能保证所有的ExpandoObjects都具有
//同一组属性,可以获取不同的属性名称的完整列表
// - 这表示列列表
var rows = dataGrid1.ItemsSource.OfType< IDictionary< string,object>>();
var columns = rows.SelectMany(d => d.Keys).Distinct(StringComparer.OrdinalIgnoreCase);

foreach(列中的字符串文本)
{
//现在为每个属性设置一个列并绑定
var column = new DataGridTextColumn
{
标题= text,
Binding = new Binding(text)
};

dataGrid1.Columns.Add(column);
}


I am attempting to display the results of a query in a WPF datagrid. The ItemsSource type I am binding to is IEnumerable<dynamic>. As the fields returned are not determined until runtime I don't know the type of the data until the query is evaluated. Each "row" is returned as an ExpandoObject with dynamic properties representing the fields.

It was my hope that AutoGenerateColumns (like below) would be able to generate columns from an ExpandoObject like it does with a static type but it does not appear to.

<DataGrid AutoGenerateColumns="True" ItemsSource="{Binding Results}"/>

Is there anyway to do this declaratively or do I have to hook in imperatively with some C#?

EDIT

Ok this will get me the correct columns:

// ExpandoObject implements IDictionary<string,object> 
IEnumerable<IDictionary<string, object>> rows = dataGrid1.ItemsSource.OfType<IDictionary<string, object>>();
IEnumerable<string> columns = rows.SelectMany(d => d.Keys).Distinct(StringComparer.OrdinalIgnoreCase);
foreach (string s in columns)
    dataGrid1.Columns.Add(new DataGridTextColumn { Header = s });

So now just need to figure out how to bind the columns to the IDictionary values.

解决方案

Ultimately I needed to do two things:

  1. Generate the columns manually from the list of properties returned by the query
  2. Set up a DataBinding object

After that the built-in data binding kicked in and worked fine and didn't seem to have any issue getting the property values out of the ExpandoObject.

<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Results}" />

and

// Since there is no guarantee that all the ExpandoObjects have the 
// same set of properties, get the complete list of distinct property names
// - this represents the list of columns
var rows = dataGrid1.ItemsSource.OfType<IDictionary<string, object>>();
var columns = rows.SelectMany(d => d.Keys).Distinct(StringComparer.OrdinalIgnoreCase);

foreach (string text in columns)
{
    // now set up a column and binding for each property
    var column = new DataGridTextColumn 
    {
        Header = text,
        Binding = new Binding(text)
    };

    dataGrid1.Columns.Add(column);
}

这篇关于如何在WPF DataGrid中动态生成列?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆