Telerik Grid MVC Dynamic Columns using DataTable

Telerik Grid MVC Dynamic Columns using DataTable

TelerikMVC_DynamicColumns.rar

The project use [.net Framework 4.0 ],[MVC 3.0],[Telerik 2011.3.1115.340]

imageimage

Result:

image

The Dynamic Columns is change from 20 to 30

image             image


實作(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()" />
                    &nbsp;
                    <input type="reset" name="btnReset" value="Reset" id="btnReset" />
                    &nbsp;
                </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

參考網址:http://www.telerik.com/community/forums/aspnet-mvc/grid/telerik-grid-mvc-using-a-dynamic-datatable-with-ajax-binding.aspx

 

Demo Project You Can Download

 

iverson.huang 筆記