用扩展方法实现DevExpress-GridControl级联效果
首先,让我们先回顾下.Net中扩展方法的特征:
1、 必须在一个非嵌套、非泛型的静态类中;
2、 至少有一个参数(this 作前缀的参数);
3、 第一个参数必须附加this做前缀;
4、 第一个参数不能加任何修饰符(如out或ref);
5、 第一个参数的类型不能是指针类型。
在DevExpress控件中GridControl是非常常用的控件之一,有时后为更好的展示效果而使用级联功能。在通常情况下为实现这种功能需要在一个实体类中建立令一个实体类的集合(该集合以备级联下的GridView使用),这样实行增加类实体类的复杂程度,且在项目比较大的情况下这种模式更降低了程序的可读性与可维护性,在此写了GridControl的扩展类,使整个项目都可以按照统一的模式建立GridControl的级联效果,且简化了实体类。
方法如下:
首先,建立GridControl,并对GridView的列绑定好相应的字段名称,在这就不细说啦。
其次,建立扩展类:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using DevExpress.XtraGrid; using DevExpress.XtraGrid.Views.Grid; namespace DXApplication3 { public static class GridViewMasterExtenstion { static Dictionary<int, IEnumerable<string>> _relationNames; static Dictionary<int, Action<GridView, MasterRowGetRelationNameEventArgs>> _displayCaptions; static Dictionary<int, Action<GridView, MasterRowGetChildListEventArgs>> _childLists; static GridViewMasterDetailExtenstion() { _relationNames = new Dictionary<int, IEnumerable<string>>(); _displayCaptions = new Dictionary<int, Action<GridView, MasterRowGetRelationNameEventArgs>>(); _childLists = new Dictionary<int, Action<GridView, MasterRowGetChildListEventArgs>>(); } public static void MasterDetails(this GridView gridView, string relationName, Action<GridView, MasterRowGetChildListEventArgs> childLists) { MasterDetails(gridView, new[] { relationName }, null, childLists); } public static void MasterDetails(this GridView gridView, IEnumerable<string> relationNames, Action<GridView, MasterRowGetChildListEventArgs> childLists) { MasterDetails(gridView, relationNames, null, childLists); } public static void MasterDetails(this GridView gridView, IEnumerable<string> relationNames, Action<GridView, MasterRowGetRelationNameEventArgs> displayCaptions, Action<GridView, MasterRowGetChildListEventArgs> childLists) { if (relationNames == null) { throw new ArgumentNullException("relationNames can not be null."); } _relationNames[gridView.GetHashCode()] = relationNames; if (displayCaptions != null) _displayCaptions[gridView.GetHashCode()] = displayCaptions; _childLists[gridView.GetHashCode()] = childLists; gridView.MasterRowEmpty += GridView_MasterRowEmpty; gridView.MasterRowGetChildList += GridView_MasterRowGetChildList; gridView.MasterRowGetRelationName += GridView_MasterRowGetRelationName; gridView.MasterRowGetRelationCount += GridView_MasterRowGetRelationCount; gridView.MasterRowGetRelationDisplayCaption += GridView_MasterRowGetRelationDisplayCaption; } private static void GridView_MasterRowEmpty(object sender, MasterRowEmptyEventArgs e) { if (e.RowHandle == GridControl.InvalidRowHandle) return; e.IsEmpty = false; } private static void GridView_MasterRowGetChildList(object sender, MasterRowGetChildListEventArgs e) { if (e.RowHandle == GridControl.InvalidRowHandle) return; var key = GetGridViewHashCode(sender as GridView); if (_childLists.ContainsKey(key)) { var childList = _childLists[key]; childList(sender as GridView, e); } } private static void GridView_MasterRowGetRelationCount(object sender, MasterRowGetRelationCountEventArgs e) { var key = GetGridViewHashCode(sender as GridView); if (_relationNames.ContainsKey(key)) e.RelationCount = _relationNames[key].Count(); else e.RelationCount = 0; } private static void GridView_MasterRowGetRelationName(object sender, MasterRowGetRelationNameEventArgs e) { if (e.RowHandle == GridControl.InvalidRowHandle) return; var key = GetGridViewHashCode(sender as GridView); if (_relationNames.ContainsKey(key)) { e.RelationName = _relationNames[key].Skip(e.RelationIndex).FirstOrDefault(); } } private static void GridView_MasterRowGetRelationDisplayCaption(object sender, MasterRowGetRelationNameEventArgs e) { if (e.RowHandle == GridControl.InvalidRowHandle) return; var key = GetGridViewHashCode(sender as GridView); if (_displayCaptions.ContainsKey(key)) { var displayCaptions = _displayCaptions[key]; displayCaptions(sender as GridView, e); } } private static int GetGridViewHashCode(GridView gridView) { if (gridView.SourceView == null) return gridView.GetHashCode(); else return gridView.SourceView.GetHashCode(); } } }
最后,举例,在程序中调用:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace DXApplication3 { public partial class Form1 : DevExpress.XtraEditors.XtraForm { public Form1() { InitializeComponent(); this.CreateList(); gridControl1.DataSource = lstPerson; //调用模式如下,“Level1”对应Level的名称 gridView1.MasterDetails("Level1", (gridView2, a) => { Person item = gridView1.GetRow(gridView1.FocusedRowHandle) as Person; List<Company> lstCompany = new List<Company>(); for (int i = 0; i < 5; i++) { Company com = new Company(); com.Name = "A" + i; com.Sale = (i * 10).ToString(); lstCompany.Add(com); } a.ChildList = lstCompany; }); gridControl1.RefreshDataSource(); } List<Person> lstPerson = new List<Person>(); public void CreateList() { Person p1 = new Person(); p1.Name = "A"; p1.Address = "中国"; p1.Age = "20"; Person p2 = new Person(); p2.Name = "B"; p2.Address = "美国"; p2.Age = "21"; lstPerson.Add(p1); lstPerson.Add(p2); } } public class Person { public string Name { set; get; } public string Age { set; get; } public string Address { set; get; } } public class Company { public string Name { set; get; } public string Sale { set; get; } } }