使用反射技术,为DataGridView增加一个自动填充的扩展方法
初学C#,琢磨了一个使用反射技术,将一个List<T>泛型类自动填充到DataGridView中去的方法.
View Code 点击展开查看代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
namespace DevelopTools
{
#region TestExpand 擴展方法
/// <summary>
/// 擴展方法
/// </summary>
public static class MyExpand
{
#region AutoFitClass<T>自动使用类的属性,来填充DataGridView的列,并使用属性名作为列名
/// <summary>
/// 自动使用类的属性,来填充DataGridView的列,并使用属性名作为列名
/// </summary>
/// <typeparam name="T">泛型类</typeparam>
/// <param name="dv"></param>
/// <param name="list">实现了枚举接口的类的List</param>
/// <param name="listfield">是否枚举类的公用字段</param>
/// <param name="reset">是否清除原数据</param>
/// <returns>返回数据行数</returns>
public static int AutoFill<T>(this DataGridView dv, IEnumerable<T> list, bool listfield, bool reset)
{
int rowcount = list.Count<T>();
if (rowcount <= 0)
return 0;
if (reset)
{
dv.Rows.Clear();
dv.Columns.Clear();
}
// 1. 利用反射,求得类的所有公开属性及公开字段
T listfirst = list.First<T>();
Type t = listfirst.GetType();
PropertyInfo[] props = t.GetProperties(BindingFlags.Public | BindingFlags.Instance);
FieldInfo[] fields = t.GetFields();
// 2. 遍历属性,取得属性名,作为列名添加到DataGridView中.
foreach (PropertyInfo p in props)
{
if(dv.Columns.Contains(p.Name ))
continue ;
dv.Columns.Add(p.Name, p.Name);
}
// 3. 如果有要求输出字段,则遍历公用字段,并也作为列名添加到DataGridView中.
if (listfield)
{
foreach (FieldInfo field in fields) // 遍历公用字段
{
if (dv.Columns.Contains(field.Name))
continue;
dv.Columns.Add(field.Name, field.Name);
}
}
// 4. 循环读取 list 中的各行数据,写入到 DataGridView中。
foreach (T listitem in list )
{
int rowNo = dv.Rows.Add(1);
foreach (PropertyInfo p in props) //遍历属性
{
dv.Rows[rowNo].Cells[p.Name].Value = p.GetValue(listitem, null);
}
if (listfield)
{
foreach (FieldInfo f in fields) // 遍历公用字段
{
dv.Rows[rowNo].Cells[f.Name ].Value = f.GetValue(listfirst);
}
}
}
return rowcount ;
}
#endregion
}
#endregion
}
使用示例:
View Code 点击展开查看代码
#region GetProcessID 取系统进程PID
public class GetProcessID
{
public static IEnumerable<ProcessItem> GetProcesses()
{
return Process.GetProcesses().Select(p => new ProcessItem(p));
}
}
#endregion
#region ProcessItem 系统进程PID记录类
/// <summary>
/// 系统进程PID记录类
/// </summary>
public class ProcessItem
{
public int Pid { get; private set; }
public int Hwnd { get; private set; }
public int ParentHwnd { get; private set; }
public string Name { get; private set; }
public string Title { get; private set; }
public string FileName { get; private set; }
public ProcessItem(System.Diagnostics.Process p)
{
Pid = p.Id; // 进程PID
Name = p.ProcessName; // 进程名称
Title = p.MainWindowTitle; // 进程主窗口文本
ParentHwnd = (int)p.MainWindowHandle; // 进程主窗口句柄
try
{
Hwnd = (int)p.Handle; // 进程句柄. 对于系统进程,有时权限不足,不用try会抛出异常
FileName = p.MainModule.FileName; // 对应的程序文件名
}
catch
{
}
}
}
#endregion
// 取得当前系统的所有进程. 将系统进程填充到DataGridView
private void button1_Click(object sender, EventArgs e)
{
IEnumerable<ProcessItem> pitems = GetProcessID.GetProcesses(); // 取得当前系统的所有进程.
dataGridView1.AutoFill<ProcessItem>(pitems, false , true); // 将系统进程填充到DataGridView中
}