显示MyClass到DataGridView的列表

时间:2015-11-18 14:39:44

标签: c# winforms datagridview

我正在尝试将MyClass列表中的所有数据显示到DataGridView以进行故障排除。所以我在我的应用程序中实现了以下代码(来自Marc Gravell的帖子here)。它执行,但尽管我的List包含数据,props.Count和values.Length始终为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 = "";
}

3 个答案:

答案 0 :(得分:2)

您的课程仅包含字段。您正在使用的代码以及数据绑定和TypeDescriptor服务通常需要公共属性

要解决此问题,请将字段转换为自动属性。如果您使用的是C#6(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;
        // ...
    }
}

您无需使用false的{​​{1}}和bool的{​​{1}}等默认值初始化属性。

最后,完成后该功能应该有效。但正如我在评论中提到的,一旦你有0,就可以直接将它用作数据网格视图的数据源 - 无需先将其转换为int

答案 1 :(得分:1)

虽然Ivan Stoev回答了我上面提到的问题,但这是我发现的问题的替代解决方案(感谢他的帮助),现在正在使用。这将返回由公共字段组成的DataTable&#39;列表中的类。认为它可能会帮助将来的某个人。谢谢伊万!

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

答案 2 :(得分:0)

例如,如果您使用List<object>调用该方法,那么您将始终获得空结果,因为object类型没有属性。