向DataGridView显示MyClass的列表

本文关键字:列表 MyClass 显示 DataGridView | 更新日期: 2023-09-27 18:22:39

为了进行故障排除,我正在尝试将MyClass列表中的所有数据显示给DataGridView。因此,我在应用程序中实现了下面的代码(来自MarcGravell的帖子)。它执行,但尽管我的列表包含数据,道具。计数和值。长度始终为0。因此,返回的DataTable没有行或列。

我做错了什么?

public static DataTable ToDataTable<T>(IList<T> data)
{
    PropertyDescriptorCollection props =
        TypeDescriptor.GetProperties(typeof(T));
    DataTable table = new DataTable();
    for (int i = 0; i < props.Count; i++)
    {
        PropertyDescriptor prop = props[i];
        table.Columns.Add(prop.Name, prop.PropertyType);
    }
    object[] values = new object[props.Count];
    foreach (T item in data)
    {
        for (int i = 0; i < values.Length; i++)
        {
            values[i] = props[i].GetValue(item);
        }
        table.Rows.Add(values);
    }
    return table;
}

我的呼叫代码:

dgv.DataSource = Globals.ToDataTable(Lines_Formatted);

我的班级:

public class LineData
{
    public string RowID = "";
    public bool MissingMatchingPunch = false;
    public bool ScheduleIssueWithPunches = false;
    public bool ScheduledTimeAmountMet = true;
    public bool Approved_TimeEntry = true;
    public bool Approved_PunchIn = true;
    public bool Approved_PunchOut = true;
    public DateTime DateApplicable = DateTime.MinValue;
    public string TimeType = "";
    public int TimeType_CID = -1;
    public Double HoursWorked = 0;
    public double Amount = 0;
    public DateTime PunchIn = DateTime.MinValue;
    public DateTime PunchOut = DateTime.MinValue;
    public Double DailyTotal = 0;
    public Double CumulativeTotal = 0;
    public string EnteredBy = "";
    public LineType LineTypeKey;
    public enum LineType
    {
        PunchEntry = 1,
        TimeEntry = 2,
        BlankLine = 5
    }
    public string CID_Time = "";
    public string CID_PunchIn = "";
    public string CID_PunchOut = "";
    public string Account_CID = "";
}

向DataGridView显示MyClass的列表

您的类只包含字段。您正在使用的代码、数据绑定和TypeDescriptor服务通常需要公共属性

若要解决此问题,请将字段转换为自动属性。如果你使用的是C#(VS2015),那么像这个一样插入{ get; set; }就很简单了

public class LineData
{
    public string RowID { get; set; } = "";
    public bool MissingMatchingPunch { get; set; } = false;
    public bool ScheduleIssueWithPunches { get; set; } = false;
    // ....
}

如果使用的是较旧的C#版本,则需要添加{ get; set; }部分,但需要在类构造函数中移动初始化。

public class LineData
{
    public string RowID { get; set; }
    public bool MissingMatchingPunch { get; set; }
    public bool ScheduleIssueWithPunches { get; set; }
    // ....
    public LineData()
    {
        RowID = "";
        MissingMatchingPunch = false;
        ScheduleIssueWithPunches = false;
        // ...
    }
}

您不需要使用默认值初始化属性,如boolfalseint0等。

最后,完成此操作后,函数应该可以工作。但正如我在评论中提到的,一旦有了List<LineData>,就可以直接将其用作数据网格视图的数据源,而无需首先将其转换为DataTable

尽管Ivan Stoev回答了我上面的问题,但这里是我后来发现的(多亏了他的帮助)并正在使用的问题的替代解决方案。这将返回一个由列表中类的公共"字段"组成的DataTable。我想这可能会在将来帮助到别人。谢谢伊凡!

    public static DataTable ToDataTable<T>(List<T> data)
    {
        FieldInfo[] fields = typeof(T).GetFields();
        DataTable table = new DataTable();
        for (int i = 0; i < fields.Length; i++)
        {
            FieldInfo FI = fields[i];
            table.Columns.Add(FI.Name, FI.FieldType);
        }
        object[] values = new object[fields.Length];
        foreach (T item in data)
        {
            for (int i = 0; i < values.Length; i++)
            {
                values[i] = fields[i].GetValue(item);
            }
            table.Rows.Add(values);
        }
        return table;
    }

例如,如果使用List<object>调用方法,那么由于object类型没有属性,因此总是会得到一个空结果。