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

And*_*ndy 68 c# wpf datagrid silverlight-2.0 wpf-controls

我是WPF的新手.我只想知道如何以编程方式将列和行添加到WPF中的DataGrid.我们过去常常在Windows窗体中执行此操作.创建表列和行,并将其绑定到DataGrid.

我相信WPF DataGrid与ASP.net和Windows形式中使用的有点不同(如果我错了,请纠正我).

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

Joh*_*zek 69

以编程方式添加一行:

DataGrid.Items.Add(new DataItem());
Run Code Online (Sandbox Code Playgroud)

以编程方式添加列:

DataGridTextColumn textColumn = new DataGridTextColumn(); 
textColumn.Header = "First Name"; 
textColumn.Binding = new Binding("FirstName"); 
dataGrid.Columns.Add(textColumn); 
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请查看WPF DataGrid讨论板上的这篇文章.

  • -1:因为您显示了非常简单的部分,而不是如何将数据实际绑定到那些运行时添加的列.我确信Andy想要构建一个显示某种数据的应用程序,而不仅仅是列名. (4认同)

小智 28

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

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

        }
Run Code Online (Sandbox Code Playgroud)


Bar*_*ski 22

我有同样的问题.向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);
Run Code Online (Sandbox Code Playgroud)

//编辑:

请注意,这不是组件应该如何使用的方式,但是,如果您只有编程生成的数据(例如,在我的情况下:一系列功能和神经网络输出),它会简化很多.


Joh*_*hnB 11

我找到了一个在运行时添加列的解决方案,并绑定到DataTable.

不幸的是,有47列以这种方式定义,它不能足够快地绑定到数据上.有什么建议?

XAML

<DataGrid
  Name="dataGrid"
  AutoGenerateColumns="False"
  ItemsSource="{Binding}">
</DataGrid>
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

  • 为什么在绑定路径中使用"[{0}]"?它对我不起作用,但是当我只使用没有正方形和曲线的名称时它会起作用吗? (2认同)

dob*_*lak 5

编辑:抱歉,我不再有下面提到的代码。这是一个巧妙的解决方案,尽管很复杂。


我发布了一个示例项目,描述如何将 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; }
Run Code Online (Sandbox Code Playgroud)

您可以这样定义列:

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) 
Run Code Online (Sandbox Code Playgroud)

或者更好的是,如果是一些真实的物体

public class User 
{
    public string FirstName { get; set; }
    public string LastName{ get; set; }
    ...
}
Run Code Online (Sandbox Code Playgroud)

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

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);
Run Code Online (Sandbox Code Playgroud)

然后,您只需绑定到用户集合,列就会根据您的指定自动生成。传递给属性描述符的字符串是列标题的名称。在运行时,您可以向“用户”添加更多 PropertyDescriptors,向网格添加另一列。