以编程方式将列和行添加到WPF Datagrid

我是新来的WPF。 我只想知道我们应该如何以编程方式将列和行添加到WPF中的DataGrid。 我们用Windows窗体来做的方式。 创build表格列和行,并将其绑定到DataGrid。

我相信WPF的DataGrid是有点不同ASP.net和Windows窗体中使用(纠正我,如果我错了)。

我有我需要在DataGrid中绘制的行数和列数,以便用户可以编辑单元格中的数据。

以编程方式添加一行:

DataGrid.Items.Add(new DataItem()); 

以编程方式添加一列:

 DataGridTextColumn textColumn = new DataGridTextColumn(); textColumn.Header = "First Name"; textColumn.Binding = new Binding("FirstName"); dataGrid.Columns.Add(textColumn); 

查看WPF DataGrid讨论板上的这篇文章 ,了解更多信息。

试试这个吧,它可以工作100%:以编程方式添加列和行:首先需要创build项目类:

 public class Item { public int Num { get; set; } public string Start { get; set; } public string Finich { get; set; } } private void generate_columns() { DataGridTextColumn c1 = new DataGridTextColumn(); c1.Header = "Num"; c1.Binding = new Binding("Num"); c1.Width = 110; dataGrid1.Columns.Add(c1); DataGridTextColumn c2 = new DataGridTextColumn(); c2.Header = "Start"; c2.Width = 110; c2.Binding = new Binding("Start"); dataGrid1.Columns.Add(c2); DataGridTextColumn c3 = new DataGridTextColumn(); c3.Header = "Finich"; c3.Width = 110; c3.Binding = new Binding("Finich"); dataGrid1.Columns.Add(c3); dataGrid1.Items.Add(new Item() { Num = 1, Start = "2012, 8, 15", Finich = "2012, 9, 15" }); dataGrid1.Items.Add(new Item() { Num = 2, Start = "2012, 12, 15", Finich = "2013, 2, 1" }); dataGrid1.Items.Add(new Item() { Num = 3, Start = "2012, 8, 1", Finich = "2012, 11, 15" }); } 

我有同样的问题。 向WPF DataGrid添加新行需要一个技巧。 DataGrid依赖项目对象的属性字段。 ExpandoObject可以dynamic添加新的属性。 下面的代码解释了如何做到这一点:

 // using System.Dynamic; DataGrid dataGrid; string[] labels = new string[] { "Column 0", "Column 1", "Column 2" }; foreach (string label in labels) { DataGridTextColumn column = new DataGridTextColumn(); column.Header = label; column.Binding = new Binding(label.Replace(' ', '_')); dataGrid.Columns.Add(column); } int[] values = new int[] { 0, 1, 2 }; dynamic row = new ExpandoObject(); for (int i = 0; i < labels.Length; i++) ((IDictionary<String, Object>)row)[labels[i].Replace(' ', '_')] = values[i]; dataGrid.Items.Add(row); 

//编辑:

请注意,这不是如何使用组件的方式,但是,如果只有编程生成的数据(例如,在我的情况下:一系列function和neural network输出),它会简化很多。

我find了一个在运行时添加列的解决scheme,并绑定到一个DataTable

  • 如何将WPF DataGrid绑定到可变数量的列?

不幸的是,以这种方式定义了47列,它并没有足够快地绑定到我的数据上。 有什么build议么?

XAML

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

xaml.cs使用System.Windows.Data;

 if (table != null) // table is a DataTable { foreach (DataColumn col in table.Columns) { dataGrid.Columns.Add( new DataGridTextColumn { Header = col.ColumnName, Binding = new Binding(string.Format("[{0}]", col.ColumnName)) }); } dataGrid.DataContext = table; } 

编辑 :对不起,我不再有下面提到的代码。 这是一个很好的解决办法,虽然很复杂。


我发布了一个示例项目,描述如何使用PropertyDescriptor和lambda委托与dynamicObservableCollection和DynamicObject填充强types列定义的网格。

列可以在运行时dynamic添加/删除。 如果您的数据不是具有已知types的对象,则可以创build一个数据结构,以便可以通过任意数量的列进行访问,并为每个“列”指定一个PropertyDescriptor。

例如:

 IList<string> ColumnNames { get; set; } //dict.key is column name, dict.value is value Dictionary<string, string> Rows { get; set; } 

你可以这样定义列:

 var descriptors= new List<PropertyDescriptor>(); //retrieve column name from preprepared list or retrieve from one of the items in dictionary foreach(var columnName in ColumnNames) descriptors.Add(new DynamicPropertyDescriptor<Dictionary, string>(ColumnName, x => x[columnName])) MyItemsCollection = new DynamicDataGridSource(Rows, descriptors) 

甚至更好,如果有一些真实的物体

 public class User { public string FirstName { get; set; } public string LastName{ get; set; } ... } 

您可以指定强types的列(与您的数据模型相关):

 var propertyDescriptors = new List<PropertyDescriptor> { new DynamicPropertyDescriptor<User, string>("First name", x => x.FirstName ), new DynamicPropertyDescriptor<User, string>("Last name", x => x.LastName ), ... } var users = retrieve some users Users = new DynamicDataGridSource<User>(users, propertyDescriptors, PropertyChangedListeningMode.Handler); 

然后,您只需绑定到用户集合,并按照您的说明自动生成列。 传递给属性描述符的string是列标题的名称。 在运行时你可以添加更多的PropertyDescriptors到'用户'添加另一列到网格。

如果你已经有数据绑定John Myczek的答案已经完成。
如果不是,你至less有2个选项,我知道如果你想指定你的数据的来源。 (但是我不确定这是否符合大多数指导原则,如MVVM)

选项1:像JohnB说的那样。 但我认为你应该使用你自己定义的集合,而不是一个弱types的DataTable(没有冒犯,但是你不能从代码中知道每一列代表什么)

xaml.cs

 DataContext = myCollection; //myCollection is a `ICollection<YourType>` preferably `ObservableCollection<YourType> - option 2) Declare the name of the Datagrid in xaml <WpfToolkit:DataGrid Name=dataGrid}> 

xaml.cs中

 CollectionView myCollectionView = (CollectionView)CollectionViewSource.GetDefaultView(yourCollection); dataGrid.ItemsSource = myCollectionView; 

如果你的types有一个名字定义的属性,那么你可以做什么约翰Myczek指出。

 DataGridTextColumn textColumn = new DataGridTextColumn(); dataColumn.Header = "First Name"; dataColumn.Binding = new Binding("FirstName"); dataGrid.Columns.Add(textColumn); 

如果你不知道你需要在你的dataGrid中显示的属性,这显然是行不通的,但是如果是这样的话,你将会遇到更多的问题需要处理,而且我相信这里没有范围。

如果你已经有数据绑定John Myczek的答案已经完成。 如果不是,你至less有2个选项,我知道如果你想指定你的数据的来源。 (但是我不确定这是否符合大多数指导原则,如MVVM)

然后,您只需绑定到用户集合,并按照您的说明自动生成列。 传递给属性描述符的string是列标题的名称。 在运行时你可以添加更多的PropertyDescriptors到'用户'添加另一列到网格。