我想知道在WPF中如何通过编程方式向DataGrid添加列和行。就像我们在Windows窗体中所做的那样-创建表格列和行,然后将其绑定到DataGrid。
我有一定数量的行和列需要在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讨论板块上查看此帖以获取更多信息。
试试这个,百分之百有效:动态添加行和列:
你需要首先创建一个项目类:
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
可以动态地添加新属性。下面的代码解释了如何实现:
// 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);
//编辑:
请注意,这不是组件应该使用的方式,然而如果您只有编程生成的数据(例如,在我的情况下:一系列特征和神经网络输出),这样做可以简化许多操作。
DataTable
的解决方案。
不幸的是,使用这种方式定义了47个列之后,数据绑定速度不够快。有什么建议吗?
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委托以动态ObservableCollection和DynamicObject填充具有强类型列定义的网格。
列可以在运行时动态地添加/删除。如果您的数据不是已知类型的对象,则可以创建一个数据结构,使其能够通过任意数量的列进行访问,并为每个“列”指定一个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; }
...
}
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);
然后,您只需绑定到用户集合,列将按您指定的方式自动生成。传递给属性描述符的字符串是列标题的名称。在运行时,您可以向“用户”添加更多PropertyDescriptor并将另一列添加到网格中。
DataContext = myCollection;
//myCollection is a `ICollection<YourType>` preferably
`ObservableCollection<YourType>
- option 2) Declare the name of the Datagrid in xaml
<WpfToolkit:DataGrid Name=dataGrid}>
CollectionView myCollectionView =
(CollectionView)CollectionViewSource.GetDefaultView(yourCollection);
dataGrid.ItemsSource = myCollectionView;
DataGridTextColumn textColumn = new DataGridTextColumn();
dataColumn.Header = "First Name";
dataColumn.Binding = new Binding("FirstName");
dataGrid.Columns.Add(textColumn);
如果您不知道需要在数据网格中显示哪些属性,那么显然这种方法无法奏效,但如果是这种情况,您将面临更多问题,我相信这已经超出了本文的范围。
然后,您只需绑定到用户集合,列将根据您指定的自动生成。传递给属性描述符的字符串是列标题的名称。在运行时,您可以向“用户”添加更多PropertyDescriptor,以在网格中添加另一列。
在 CodeBehind 中将 DataTable 绑定到 DataGridTextColumn xaml
<DataGrid
Name="TrkDataGrid"
AutoGenerateColumns="False"
ItemsSource="{Binding}">
</DataGrid>
xaml.cs
foreach (DataColumn col in dt.Columns)
{
TrkDataGrid.Columns.Add(
new DataGridTextColumn
{
Header = col.ColumnName,
Binding = new Binding(string.Format("[{0}]", col.ColumnName))
});
}
TrkDataGrid.ItemsSource= dt.DefaultView;
Binding("[FirstName]")
请参见我下面的先前答案,它也可以工作,但是在绑定大型数据集时速度明显较慢。 - JohnBDataItem
应该长什么样子? - C4d