为了进行故障排除,我正在尝试将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 = "";
}
您的类只包含字段。您正在使用的代码、数据绑定和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;
// ...
}
}
您不需要使用默认值初始化属性,如bool
的false
和int
的0
等。
最后,完成此操作后,函数应该可以工作。但正如我在评论中提到的,一旦有了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
类型没有属性,因此总是会得到一个空结果。