DataGridView列名来自对象属性值?

时间:2011-03-16 02:44:06

标签: c# winforms linq datagridview linq-to-objects

public class Employee
{
  public int ColumnName {set; get;}
  public int RowOrder {set; get;}
  public string TabName {set; get;}
  public string Names {set; get;}
}

BindingList<Employee> workers = new BindingList<Employee>();
workers.Add(new Employee(1, 0, "Foo", "Bob Jones"));
workers.Add(new Employee(2, 0, "Foo", "Jane Jones"));
workers.Add(new Employee(3, 0, "Foo", "Jim Jones"));
workers.Add(new Employee(1, 1, "Foo", "Joe Jones"));
workers.Add(new Employee(3, 1, "Foo", "John Jones"));
workers.Add(new Employee(1, 0, "Bar", "Worker Bee1"));
workers.Add(new Employee(2, 0, "Bar", "Worker Bee2"));    

我有一个带标签条的winform。选项卡可以动态添加,并且与TabName属性的名称相同。每个选项卡都包含一个DataGridView,其名称也与TabName属性相同。

因此,每个tab / gridview应该只显示来自正确对象的数据(foo选项卡只显示网格中的foo人员等)。我希望列名称是每个对象中ColumnName的值(例如1,2,3),我希望RowOrder是名称出现的行号。所以我正在寻找看起来的输出如下:

1           2           3
==================================
Bob Jones   Jane Jones  Jim Jones
Joe Jones               John Jones

如果网格坐标不包含值,则应将其留空。

我对winforms编程相对较新 - 搜索给我留下了更多关于最佳方法的问题。我设置了通用数据绑定到对象列表,但是这给我留下了以每个属性命名的列(ColumnName,RowOrder等),我不会提到这不解决我的每个tab / datagrid只显示数据

linq表达式是将每个DataGridView组合在一起的好方法吗?如果是这样,我如何制作一个表达式,将列名更改为ColumnName中的值?我可以通过RowOrder订购,让每一行都正确,留下空格吗?

如果我只是创建其他对象列表来填充每个标签/网格并手动进行排序/堆叠,我会更好吗?

1 个答案:

答案 0 :(得分:1)

首先,您需要重新组织数据结构。包含行号和列号的名称列表无济于事。根据tab包含的表,包含包含行包含名称的表。

private void AddRow(DataTable dt, params string[] names)
{
    // Expand columns as required
    while (dt.Columns.Count < names.Length)
    {
        DataColumn col = dt.Columns.Add();
        col.ColumnName = dt.Columns.Count.ToString();
    }
    // Add new row
    DataRow row = dt.NewRow();
    for (int i = 0; i < names.Length; i++)
        row[i] = names[i];
    dt.Rows.Add(row);
}
private void AddToColumn(DataTable dt, int rowIdx, int colIdx, string name)
{
    while (dt.Columns.Count < colIdx)
    {
        DataColumn col = dt.Columns.Add();
        col.ColumnName = dt.Columns.Count.ToString();
    }
    if (dt.Rows.Count > 0)
    {
        while (dt.Rows[0].ItemArray.Length < colIdx)
            dt.Rows[0][dt.Rows[0].ItemArray.Length] = "";
    }
    DataRow row;
    if (rowIdx < dt.Rows.Count)
    {
        row = dt.Rows[rowIdx];
        row[colIdx - 1] = name;
    }
    else
    {
        row = dt.NewRow();
        row[colIdx - 1] = name;
        dt.Rows.Add(row);
    }
}
private void buttonStart_Click(object sender, EventArgs e)
{
    Dictionary<string, DataTable> workers = new Dictionary<string, DataTable>();

    DataTable dt = new DataTable();
    AddRow(dt, "Bob Jones", "Jane Jones", "Jim Jones");
    AddRow(dt, "Joe Jones", "", "John Jones");
    workers.Add("Foo", dt);

    AddToColumn(dt, 0, 4, "Testing"); // Use this if you have to add by column

    dt = new DataTable();
    AddRow(dt, "Worker Bee1",  "Worker Bee2");
    workers.Add("Bar", dt);

    string tabName = "Foo";
    dataGridView1.DataSource = workers.FirstOrDefault(x => x.Key == tabName).Value;
}