今天在开发工做中遇到了一个问题:编程
个人不少DataGridView,由于数据源(DataSource)使用的是数组,致使在点击每列列头的时候没法就指定列进行排序数组
所以我须要写一个将数组转换为DataTable的函数。函数
在网上查了一下,找到了这篇Blog,总结得比较全面:测试
http://blog.csdn.net/emoonight/article/details/6617683this
不过这篇Blog中,从数组转换成DataTable的函数(函数ToDataTable<T>)有一个BUG,在建立每一个数据行的时候,没有对list的元素进行判空操做。这样作在数组中有元素为空时,会致使TargetException,更有甚者若是把这段代码运用到Load函数的时候,有可能函数直接中断执行且不弹出任何异常。.net
下面是我改造以后的代码(须要引用System.Reflection):code
public static class DataHelper { public static DataTable GetDataTable<T>(this IEnumerable<T> list) { DataTable dtResult = new DataTable(); List<PropertyInfo> propertiyInfos = new List<PropertyInfo>(); //生成各列 Array.ForEach<PropertyInfo>(typeof(T).GetProperties(), p => { propertiyInfos.Add(p); dtResult.Columns.Add(p.Name, p.PropertyType); }); //生成各行 foreach (var item in list) { if (item == null) { continue; } DataRow dataRow = dtResult.NewRow(); propertiyInfos.ForEach(p => dataRow[p.Name] = p.GetValue(item, null)); dtResult.Rows.Add(dataRow); } return dtResult; } }
我写了个例子,作了如下测试。orm
创建一个Windows窗体应用程序,工程名为Array2DataTableblog
创建一个类Hero,里面有五个属性:排序
public class Hero { public Hero(int id, string name, int strength, int dexterity, int intelligence) { this.idField = id; this.nameField = name; this.strengthField = strength; this.dexterityField = dexterity; this.intelligenceField = intelligence; } private int idField; public int id { get { return idField; } set { idField = value; } } private string nameField; public string name { get { return nameField; } set { nameField = value; } } private int strengthField; public int strength { get { return strengthField; } set { strengthField = value; } } private int dexterityField; public int dexterity { get { return dexterityField; } set { dexterityField = value; } } private int intelligenceField; public int intelligence { get { return intelligenceField; } set { intelligenceField = value; } } }
在FormMain中的Load函数中加入下面代码:
private void FormMain_Load(object sender, EventArgs e) { Hero[] heros = new Hero[10]; heros[0] = new Hero(1, "秃驴", 59, 64, 78); heros[1] = new Hero(2, "独眼龙", 96, 99, 94); heros[2] = new Hero(3, "三脚猫", 50, 88, 73); heros[3] = new Hero(4, "绿帽王八", 79, 77, 61); heros[4] = new Hero(5, "四眼田鸡", 89, 93, 63); heros[5] = new Hero(6, "地头蛇", 71, 70, 58); heros[6] = new Hero(7, "单身狗", 95, 82, 89); heros[7] = new Hero(8, "替罪羊", 90, 81, 93); heros[8] = new Hero(9, "黄牛", 81, 52, 67); dgvArray.DataSource = heros; dgvDataTable.DataSource = DataHelper.GetDataTable<Hero>(heros); }
程序运行后的效果以下,能够看到,以DataTable为数据源的DataGridView(dgvDataTable),已经能够点击列首进行排序了:
若是但愿某几列能够排序,某几列不能够排序,能够手动将这些列的信息添加到DataGridView的列中,并配置好DataPropertyName,最后在“编辑列”中设置“SortMode”属性,该属性的值为System.Windows.Forms.DataGridViewColumnSortMode 类型枚举。这个枚举下有三个值,现将三者列在下面,其中的说明信息摘自VS中反射到的元数据:
1)DataGridViewColumnSortMode.NotSortable
-此列仅能以编程方式进行排序,但因为它本来并不打算排序,因此列标头将不包含排序标志符号的空间
2)DataGridViewColumnSortMode.Automatic
-除非列标头用于进行选择,不然用户能够经过单击列标头对列进行排序。 排序标志符号将自动显示出来
3)DataGridViewColumnSortMode.Programmatic
-此列仅能以编程方式进行排序,而且列标头将包含排序标志符号的空间
这个设置的默认值都是DataGridViewColumnSortMode.Automatic
END