C#語言中對象數組到DataTable的轉換

今天在開發工做中遇到了一個問題:編程

個人不少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

相關文章
相關標籤/搜索