程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> 擴展方法(2) GridView單元格合並

擴展方法(2) GridView單元格合並

編輯:關於C#

大家GridView都用的比較多吧..有沒遇到單元格需要合並的需求..

單元格合並原理其實很簡單,就是逐行判斷要合並的單元格裡的值是否和上一行的相同,要是相同的 話就合並,不同的話就接著判斷

我們可以通過擴展方法為GridView添加單元合並

 public static class GridViewExtensions
     {
         /// <summary>
         ///  GridView行合並
         /// </summary>
         /// <param name="gridView"></param>
         /// <param name="field">合並參數(匿名類型)
         /// ColumnIndex:要合並行的索引 (以0開始,必須指定)
         /// ID(可選):如果該行為模板行則必須指定
         /// PropertyName:根據ID屬性 默認值為Text
         /// Colums:(string類型)表示額外的行合並方式和ColumnIndex一樣(多個使用逗 號隔開,如Colums="5,6,7,8")
         /// 例:
         /// 合並第一行(第一行為模板行),綁定的一個Label名稱為lblName  根據Text 屬性值合並  第6行方式和第一行相同
         /// new {ColumnIndex=0,ID="lblName",PropertyName="Text",Columns="5"}
         /// </param>
         public static GridView RowSpan(this GridView gridView, object  field)
         {
             Dictionary<string, string> rowDictionary =  ObjectLoadDictionary(field);
             int columnIndex = int.Parse(rowDictionary["ColumnIndex"]);
             string columnName = rowDictionary["ColumnName"];
             string propertyName = rowDictionary["PropertyName"];
             string columns = rowDictionary["Columns"];
             for (var i = 0; i < gridView.Rows.Count; i++)
             {

                 int rowSpanCount = 1;
                 for (int j = i + 1; j < gridView.Rows.Count;  j++)
                 {
                     //綁定行合並處理
                     if (string.IsNullOrEmpty(columnName))
                     {
                         //比較2行的值是否相同
                         if (gridView.Rows[i].Cells [columnIndex].Text == gridView.Rows[j].Cells[columnIndex].Text)
                         {
                             //合並行的數量+1
                             rowSpanCount++;
                             //隱藏相同的行
                             gridView.Rows[j].Cells [columnIndex].Visible = false;
                             if (!string.IsNullOrEmpty (columns))
                             {
                                 columns.Split (',').ToList<string>().ForEach(c => gridView.Rows[j].Cells[int.Parse (c)].Visible=false);
                             }
                         }
                         else
                         {
                             break;
                         }
                     }
                     else
                     {
                         //模板行的合並處理
                         if (GetPropertyValue(gridView.Rows [i].Cells[columnIndex].FindControl(columnName), propertyName) == GetPropertyValue (gridView.Rows[j].Cells[columnIndex].FindControl(columnName), propertyName))
                         {
                             rowSpanCount++;
                             //隱藏相同的行
                             gridView.Rows[j].Cells [columnIndex].Visible = false;
                             if (!string.IsNullOrEmpty (columns))
                             {

                                 columns.Split (',').ToList<string>().ForEach(c => gridView.Rows[j].Cells[int.Parse(c)].Visible  = false);
                             }
                         }
                         else
                         {
                             break;
                         }
                     }
                 }
                 if (rowSpanCount > 1)
                 {
                     //行合並
                     gridView.Rows[i].Cells[columnIndex].RowSpan =  rowSpanCount;
                     //判斷是否有額外的行需要合並
                     if (!string.IsNullOrEmpty(columns))
                     {
                         //額外的行合並
                         columns.Split(',').ToList<string> ().ForEach(c => gridView.Rows[i].Cells[int.Parse(c)].RowSpan = rowSpanCount);
                     }
                     i = i + rowSpanCount - 1;
                 }

             }
             return gridView;
         }

         private static Dictionary<string, string> ObjectLoadDictionary (object fields)
         {
             Dictionary<string, string> resultDictionary = new  Dictionary<string, string>();
             PropertyInfo[] property = fields.GetType().GetProperties (BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public |  BindingFlags.GetProperty);
             foreach (PropertyInfo tempProperty in property)
             {
                 resultDictionary.Add(tempProperty.Name,  tempProperty.GetValue(fields, null).ToString());
             }
             //指定默認值
             if (!resultDictionary.Keys.Contains("ColumnIndex"))
             {
                 throw new Exception("未指定要合並行的索引 ColumnIndex  屬性!");
             }
             if (!resultDictionary.Keys.Contains("ColumnName"))
             {
                 resultDictionary.Add("ColumnName", null);
             }

             if (!resultDictionary.Keys.Contains("PropertyName"))
             {
                 resultDictionary.Add("PropertyName", "Text");
             }

             if (!resultDictionary.Keys.Contains("Columns"))
             {
                 resultDictionary.Add("Columns", null);
             }
             return resultDictionary;
         }

         /// <summary>
         ///  獲取一個對象的一個屬性..
         /// </summary>
         /// <param name="obj"></param>
         /// <param name="PropertyName">屬性名稱</param>
         /// <returns>屬性的值,  如果無法獲取則返回 null</returns>
         private static object GetPropertyValue(object obj, string  PropertyName)
         {
             PropertyInfo property = obj.GetType().GetProperty (PropertyName);

             return property.GetValue(obj,null);
         }
     }

我為GridView 創建了個RowSpan的方法 .有一個object 參數 

為什要定義object 參數  源於ASP.NET MVC 的Routing 組件配置規則  感覺這種方式很不錯..

所以使用了這種方式來進行.

這個擴展方法的使用方式很簡單

 var s = new[] {
                 new { 姓名 = "張三", 性別 = "男", 語文 =  86f, 數學 = 90f, 學期 = "第一學期" },
                 new { 姓名 = "張三", 性別 = "男", 語文 = 89f,  數學 = 98f, 學期 = "第二學期" },
                 new { 姓名 = "李四", 性別 = "男", 語文 = 89f,  數學 = 64f, 學期 = "第一學期" },
                 new { 姓名 = "李四", 性別 = "男", 語文 = 75f,  數學 = 64f, 學期 = "第二學期" },
                 new { 姓名 = "王五", 性別 = "男", 語文 = 89f,  數學 = 64f, 學期 = "第一學期" },
                 new { 姓名 = "王五", 性別 = "男", 語文 = 63f,  數學 = 93f, 學期 = "第二學期" }
             };
             this.GridView1.DataSource = s;
             this.GridView1.DataBind();
             this.GridView1.RowSpan(new { ColumnIndex = 0, Columns =  "1" });

我們合並第1列的值姓名..  GirdView索引是從0開始的所以ColumnIndex=0 性別肯定和姓名對應的

可以是用Colunmns="" 這個屬性來指定哪個列的合並方式和 ColumnIndex指定的列相同  多個用 "," 隔開比如 Colunmns="2,3,4,5"這種方式

如果GridView中使用了模板列 則除了需要指定ColumnIndex外還需要添加ID和PropertyName屬性

如 new {ColumnIndex=0,ID="lblName",PropertyName="Text",Columns="1" }

ID 表示模板列的控件名稱 PropertyName 表示值來自於控件的哪個屬性.

注:暫時只能指定普通屬性如Text 或Value ;SelectedItem.Value 這種屬性需要修改部分代碼  也 不能包含容器控件 修改部分代碼可以支持容器控件

效果圖

姓名 性別 語文 數學 學期 張三 男 86 90 第一學期 89 98 第二學期 李四 男 89 64 第一學期 75 64 第二學期 王五 男 89 64 第一學期 63 93 第二學期

合並姓名和語文相同的分數

   var s = new[] {
                 new { 姓名 = "張三", 性別 = "男", 語文 =  86f, 數學 = 90f, 學期 = "第一學期" },
                 new { 姓名 = "張三", 性別 = "男", 語文 = 89f,  數學 = 98f, 學期 = "第二學期" },
                 new { 姓名 = "李四", 性別 = "男", 語文 = 89f,  數學 = 64f, 學期 = "第一學期" },
                 new { 姓名 = "李四", 性別 = "男", 語文 = 75f,  數學 = 64f, 學期 = "第二學期" },
                 new { 姓名 = "王五", 性別 = "男", 語文 = 89f,  數學 = 64f, 學期 = "第一學期" },
                 new { 姓名 = "王五", 性別 = "男", 語文 = 63f,  數學 = 93f, 學期 = "第二學期" }
             };
             this.GridView1.DataSource = s;
             this.GridView1.DataBind();
             this.GridView1.RowSpan(new { ColumnIndex = 0, Columns =  "1" });
             this.GridView1.RowSpan(new { ColumnIndex = 2 });

姓名 性別 語文 數學 學期 張三 男 86 90 第一學期 89 98 第二學期 李四 男 64 第一學期 75 64 第二學期 王五 男 89 64 第一學期 63 93 第二學期

可以使用這種方式

this.GridView1.RowSpan(new { ColumnIndex = 0, Columns = "1" }).RowSpan(new {  ColumnIndex = 2 }).RowSpan(new { ColumnIndex = 3 });

姓名 性別 語文 數學 學期 張三 男 86 90 第一學期 89 98 第二學期 李四 男 64 第一學期 75 第二學期 王五 男 89 第一學期 63 93 第二學期

還有什麼額外的參數配置 大家可以提出來 我進行改進.

效率問題 我可以考慮使用Lambda表達式樹動態創建Lambda表達式的效率

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved