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 筆記
