简体   繁体   English

显示MyClass到DataGridView的列表

[英]Show List of MyClass to DataGridView

I am trying to display all the data from my List of MyClass to a DataGridView for troubleshooting purposes. 我试图将我的MyClass列表中的所有数据显示到DataGridView以进行故障排除。 So I implemented the code below (from Marc Gravell's post here ) in my application. 所以,我实现下面的代码(由马克Gravell的帖子在这里我的应用程序)。 It executes, but despite the fact that my List contains data, the props.Count and values.Length are always 0. So the DataTable returned has no rows or columns. 它执行,但尽管我的List包含数据,props.Count和values.Length始终为0.因此返回的DataTable没有行或列。

What am I doing wrong? 我究竟做错了什么?

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

My calling code: 我的通话代码:

dgv.DataSource = Globals.ToDataTable(Lines_Formatted);

My Class: 我的课:

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

You class contains only fields . 您的类只包含字段 The code you are using, and data binding and TypeDescriptor services in general require public properties . 您正在使用的代码,数据绑定和TypeDescriptor服务通常需要公共属性

To fix the problem, turn your fields into auto properties. 要解决此问题,请将字段转换为自动属性。 If you are using C#6 (VS2015), it will be simple inserting { get; set; } 如果您使用的是C#6(VS2015),则插入{ get; set; } { get; set; } { get; set; } like this { get; set; }这样

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

If you are on older C# version, you need to add { get; set; } 如果您使用较旧的C#版本,则需要添加{ get; set; } { get; set; } { get; set; } part, but move the initialization in the class constructor. { 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;
        // ...
    }
}

You don't need to initialize properties with default values like false for bool and 0 for int etc. 您不需要使用默认值初始化属性,例如boolfalseint等为0

Finally, after doing that the function should work. 最后,完成后,该功能应该工作。 But as I mentioned in the comments, once you have a List<LineData> , you can use it directly as a data source for the data grid view - no need to first convert it to a DataTable . 但正如我在评论中提到的,一旦你有了List<LineData> ,就可以直接将它用作数据网格视图的数据源 - 无需先将其转换为DataTable

Although Ivan Stoev answered my question above, here is an alternative solution to my question that I have since discovered (thanks to his help), and am now using. 虽然Ivan Stoev回答了我上面提到的问题,但这是我自己发现的问题的替代解决方案(感谢他的帮助),现在正在使用。 This will return a DataTable comprised of the public 'fields' of the Class in the List. 这将返回由List中的Class的公共“字段”组成的DataTable。 Thought it might help someone in the future. 认为它可能会帮助将来的某个人。 Thanks Ivan! 谢谢伊万!

    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类型没有属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM