今天在開發工做中遇到了一個問題:編程
個人不少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