[.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; }
}
那如果要依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;
}
Hi,
亂馬客Blog已移到了 「亂馬客 : Re:從零開始的軟體開發生活」
請大家繼續支持 ^_^