Telerik Grid MVC Dynamic Columns using DataTable
The project use [.net Framework 4.0 ],[MVC 3.0],[Telerik 2011.3.1115.340]
Result:
The Dynamic Columns is change from 20 to 30
實作(Implementation methods):
The View needs to be strongly typed
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<TelerikMVC_DynamicColumns.Models.Index_ViewModels>" %>
index page需要自訂強型別 <TelerikMVC_DynamicColumns.Models.Index_ViewModels>
//Index View Models public class Index_ViewModels { public int ShowCount { get; set; } //is select option value(下拉選單的值) public DataTable Data { get; set; } //dynamic Columns DataTable(動態欄位合併後的資料) public IEnumerable<GridColumnSettings> Columns { get; set; }//Telerik Grid Columns Style(Telerik Grid 欄位樣式) }
The strongly typed Index_ViewModels Class
有三個屬性
int ShowCount 為下拉選單的值
DataTable Data 為動態欄位合併後的資料
IEnumerable<GridColumnSettings> Columns 為Telerik Grid 欄位樣式
The index.aspx
<h2><%: ViewBag.Message %></h2> <% using (Html.BeginForm("", "Home", FormMethod.Post, new { id = "queryform" })) {%> <script type="text/javascript"> function ShowData() { $("#ShowData").empty(); var path = "/Home/DynamicColumnsTelerikGrid"; conditionMd = $('#queryform').serializeObject(); $("#ShowData").load(path, conditionMd, null); return false; } </script> <fieldset> <legend>DynamicColumnsTelerikGrid</legend> <table> <tr> <td> DynamicColumns </td> <td> <select id="ShowCount" name="ShowCount"> <option value="20">20</option> <option value="30">30</option> </select> </td> </tr> <tr> <td colspan="2"> <input type="button" name="btnQuery" value="Query" id="btnQuery" onclick="ShowData()" /> <input type="reset" name="btnReset" value="Reset" id="btnReset" /> </td> </tr> </table> </fieldset> <%} %> <div id="ShowData"></div>
index.aspx頁面上的,Select name=ShowCount 是用
$('#queryform').serializeObject();
把form 物件,轉換為「JSON」格式
在寫在Site.Master 的 serializeObject方法
$.fn.serializeObject = function () {
var o = {};
var a = this.serializeArray();
$.each(a, function () {
if (o[this.name]) {
if (eval('!o.' + this.name + '.push')) {
eval('o.' + this.name + ' = [o[this.name]]');
}
eval('o.' + this.name + '.push(this.value || "")');
} else {
eval('o.' + this.name + ' = this.value || ""');
}
});
return o;
};
The DynamicColumnsTelerikGrid.ascx
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<TelerikMVC_DynamicColumns.Models.Index_ViewModels>" %> <% using (Html.BeginForm("", "Home", FormMethod.Post, new { id = "Data",name="Data", enctype = "multipart/form-data" })) { %> <script type="text/javascript"> var conditionMd; function Grid_OnDataBinding(e) { conditionMd = $('#Data').serializeObject(); e.data = $.extend(e.data, conditionMd); } </script> <%=Html.Hidden("ShowCount", Request["ShowCount"])%> <%} %> <%=Html.Telerik().Grid<System.Data.DataRow>(Model.Data.Rows.Cast<System.Data.DataRow>()) .Name("Grid") .Columns(columns => { //The Setting Columns style is behind to Server-Side(設定欄位樣式在Server端) columns.LoadSettings(Model.Columns as IEnumerable<GridColumnSettings>); }) .DataBinding(dataBinding => dataBinding.Ajax().Select("CustomBinding", "Home")) .Pageable(paging => paging.Position(GridPagerPosition.Both) .PageTo(1).PageSize(7, new int[] { 7, 14, 21, 28 }) .Style(GridPagerStyles.PageInput | GridPagerStyles.NextPreviousAndNumeric | GridPagerStyles.PageSizeDropDown)) .Scrollable() .ClientEvents(c => c.OnDataBinding("Grid_OnDataBinding")) %>
Telerik Grid
13行
Model.Data.Rows.Cast
DataTable 型別,把DataRow型別轉換成為指定的IEnumerable<System.Data.DataRow>
18行
columns.LoadSettings(Model.Columns as IEnumerable<GridColumnSettings>);
是behind Server-Side 設定好Dynamic Columns 欄位樣式
頁面用columns.LoadSettings方法在Telerik Client-Side 接收,所指定的樣式
The Controller
HomeController
Telerik Grid 欄位樣式的設定
1.Funtion--------> GridGolumnSettings(int DynamicColumn)
public GridColumnSettings[] SetColumnsStyle(int DynamicColumn) { int ToTal_Column = 3 + DynamicColumn; GridColumnSettings[] columns = new GridColumnSettings[ToTal_Column]; columns[0] = new GridColumnSettings { Member = "HeaderTitle", Title = "HeaderTitle", Width = "200px", HtmlAttributes = { { "style", "background:#6299D0; color:White;" } } }; columns[1] = new GridColumnSettings { Member = "HeaderValue", Title = "HeaderValue", Width = "200px" }; columns[2] = new GridColumnSettings { Member = "ItemTitle", Title = "ItemTitle", Width = "200px", HtmlAttributes = { { "style", "background:#6299D0; color:White;" } } }; for (int i = 0; i < DynamicColumn; i++) { columns[i + 3] = new GridColumnSettings { Member = Day[i], Title = Day[i], Width = "100px" }; } return columns; }
1行
GridColumnSettings 需要 using Telerik.Web.Mvc.UI
9~12行
for(int i =0; i< DynamicColumn; i++)
{
columns[i + 3] = new GridColumnSettings { Member = Day[i], Title = Day[i], Width = "100px" };
}
設定所需要的動態欄位數量
Return GridColumnSettings[] 欄位樣式陣列
資料轉向的方法
2.Funtion--------> setRow(ref DataTable new_DT, DataRow Header, DataTable Lines, int Start_Lines, int End_Lines, string HeaderTitle, string HeaderValue, string LineTitle, string LineValue)
Header and Lines Will Merge,but Lines DataTable to do directions Conversion,end Setting to new_DT.Rows
(將Header合併Lines「資料轉向」,設定至新的「new_DT.Rows」)
public void setRow(ref DataTable new_DT, DataRow Header, DataTable Lines, int Start_Lines, int End_Lines, string HeaderTitle, string HeaderValue, string LineTitle, string LineValue) { DataRow new_row = new_DT.NewRow(); new_row["HeaderTitle"] = HeaderTitle;//設定名稱HeaderTitle new_row["HeaderValue"] = Header[HeaderValue]; //get取出Header[HeaderValue]某欄位值 new_row["ItemTitle"] = LineTitle;//設定名稱ItemTitle int i = 0; for (int j = Start_Lines; j < End_Lines; j++) { //get取出Lines.Rows[j][LineValue],某欄位值 new_row[Day[i]] = Lines.Rows[j][LineValue] == null ? 0 : Lines.Rows[j][LineValue]; i++; } new_DT.Rows.Add(new_row); }
4~6行為 Header Table 欄位值
8~12行為 Lines Table 欄位值
ActionResult
[GridAction] public ActionResult DynamicColumnsTelerikGrid(Index_ViewModels md) { int DynamicColumn = 10; //Default Dynamic Columns (預設10個「動態欄位數」) if (md.ShowCount == 20) { DynamicColumn = Convert.ToInt32(GetHeader(Get_Day20Data()).Rows[0]["GroupCount"]); } else { DynamicColumn = Convert.ToInt32(GetHeader(Get_Day30Data()).Rows[0]["GroupCount"]); } //Lines(directions Conversion) will Merge Header to NewDataTable ,(Lines資料轉向後與Header,合併後的 DataTable) md.Data = _NewDataTableBinding(md, DynamicColumn); //Set Grid Columns style(設定「動態欄位數」的樣式) md.Columns = SetColumnsStyle(DynamicColumn); return View(md); } //Grid to do Change Page(Grid換頁) [GridAction] public ActionResult CustomBinding(Index_ViewModels md) { int DynamicColumn = 10; //Default Dynamic Columns (預設10個「動態欄位數」) if (md.ShowCount == 20) { DynamicColumn = Convert.ToInt32(GetHeader(Get_Day20Data()).Rows[0]["GroupCount"]); } else { DynamicColumn = Convert.ToInt32(GetHeader(Get_Day30Data()).Rows[0]["GroupCount"]); } //Lines(directions Conversion) will Merge Header to NewDataTable ,(Lines資料轉向後與Header,合併後的 DataTable) md.Data = _NewDataTableBinding(md, DynamicColumn); return View(new GridModel(md.Data)); }
13~17行
頁面初始化時的,呼叫的 ActionResult DynamicColumnsTelerikGrid(Index_ViewModels md)
需回傳兩個View Model值
md.Data
md.Columns
32~34行
Telerik Grid換頁時,呼叫的 ActionResult CustomBinding(Index_ViewModels md)
只需回傳一個View Model值
md.Data
另外 LINQ use DataTable group by 的方式:
from row in Lines.AsEnumerable() group row by new { CompanyName = row.Field<string>("CompanyName"), Location = row.Field<string>("Location") } into grp select new { CompanyName = grp.Key.CompanyName.ToString(), Location = grp.Key.Location.ToString(), GroupCount = grp.Count() }
The Lines type is DataTable
參考網址:http://alexrogan.com/?p=13
Demo Project You Can Download
iverson.huang 筆記