[.NET]讓DataGridView的Column依Class屬性上的Order順序排列

[.NET]讓DataGridView的Column依Class屬性上的Order順序排列

DataGridView的Source去Bind一個Class的List,如果DataGridView的AutoGenerateColumns屬性為true。

那Column的呈現會依Class屬性定義的順序,如下,

public class Identity
{
	public string Prop1 { get; set; }

	public int MyProperty2 { get; set; }

	[Column(Order = 1)]
	[DisplayName("帳號")]
	public string Account { get; set; }

	[Column(Order = 0)]
	public int Id { get; set; }
}

image

 

那如果要依Class中屬性上的Column設定的Order來排列就需要動點手腳。

可以在DataGridView的DataSourceChanged事件中,讀取DataSource的Type。

然後再重新設定DataGridView的Column DisplayIndex值。

所以亂馬客建立另一個ClassDataGridView 繼承自原生的 DataGridView,來處理這部份,如下,

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public class ClassDataGridView : DataGridView
    {
        public ClassDataGridView()
        {
            this.DataSourceChanged += new System.EventHandler(this.OrderColumns);
        }

        private void OrderColumns(object sender, EventArgs e)
        {
            DataGridView dg = sender as DataGridView;
            if (dg != null && dg.AutoGenerateColumns)
            {
                var t = dg.DataSource.GetType().GenericTypeArguments[0];
                var attrs = Attribute.GetCustomAttributes(t, typeof(ColumnAttribute));
                List<KeyValuePair<string, int>> ordersColumns = new List<KeyValuePair<string, int>>();

                foreach (var prop in t.GetProperties())
                {
                    var pt = prop.GetType();
                    var columnAttr = prop.GetCustomAttributes(false).OfType<ColumnAttribute>().FirstOrDefault();
                    int order = -1;
                    string propName = prop.Name;
                    
					if (columnAttr != null)
                    {
                        order = columnAttr.Order;

                    }
                    ordersColumns.Add(new KeyValuePair<string, int>(propName, order));
                }
                var orders = ordersColumns.Where(it => it.Value != -1).OrderBy(it => it.Value);
                //重新設定DataGridView的Order (Base值為0)
                foreach (var it in orders)
                {
                    dg.Columns[it.Key].DisplayIndex = it.Value;
                }
            }
        }
    }
}

 

所以在畫面拉進ClassDataGridView,然後重新給它DataSource就可以依屬性中的Order順序排列了。

{
	List<Identity> data = new List<Identity>() 
		{ new Identity { Prop1 = "1", Account = "Rainmaker", Id = 0 } };
	this.classDataGridView1.DataSource = data;
}

image

Hi, 

亂馬客Blog已移到了 「亂馬客​ : Re:從零開始的軟體開發生活

請大家繼續支持 ^_^