Telerik RadGrid AJAX更新範例

RadControls for ASP.NET AJAX是一套挺優秀的ASP.NET元件庫,包辦了開發ASP.NET專案時需要用到的大小控制項(如: Grid、日期選擇器、數字輸入欄位、頁籤... 等等),手上有幾個專案裡就是利用RadGrid的Client-Side Data-Binding實現AJAX式的換頁及重排效果,但中年人記憶消失之快已到了令人心驚的地步,每次要寫類似應用都要花上大半天回頭從舊程式找範例(要命的是連在哪個專案寫過都要想半天),於是催生了這篇"銀杏文"。

RadGridAjaxSample.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="RadGridAjaxSample.aspx.cs"
    Inherits="RadGridAjaxSample" %>
 
<%@ Register TagPrefix="telerik" Namespace="Telerik.Web.UI" Assembly="Telerik.Web.UI" %>
<!DOCTYPE html>
<html>
<head runat="server">
    <title>RadGrid AJAX Sample</title>
    <style>
        body,input { font-size: 9pt; }
        span.hi-lite { color: red; }
    </style>
    <script type="text/javascript"
            src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.js"> </script>
    <script>
        function dataBinding(sender, args) {
            //取得要傳給WebMethod的參數
            var params = args.get_methodArguments();
            //透過$.extend()加上自訂參數
            $.extend(params, { "keywd": $("#tKeyword").val() });
        }
        function dataBound(sender, args) {
            //AJAX資料Bind完成後觸發
            var kw = $("#tKeyword").val();
            //若有設關鍵字,做Highlight處理
            if (kw.length > 0) {
                var re = new RegExp(kw, "g");
                $(".u-name").each(function () {
                    var $td = $(this);
                    $td.html($td.text()
                       .replace(re, "<span class='hi-lite'>$&</span>"));
                });
            }
        }
        $(function () {
            //示範由前端觸發資料重新查詢
            $("#bQuery").click(function () {
                $find("RadGrid1").get_masterTableView().rebind();
            });
        });
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server">
    </asp:ScriptManager>
    <div style="padding: 10px;">
    關鍵字: <input id="tKeyword" /><input type="button" value="查詢" id="bQuery" />
    </div>
    <telerik:RadGrid ID="RadGrid1" runat="server" Width="400px" 
     AutoGenerateColumns="False" CellSpacing="0" GridLines="None" AllowPaging="True" 
     AllowSorting="true" PageSize="10">
        <MasterTableView>
            <Columns>
                <telerik:GridBoundColumn HeaderText="會員編號"
                    DataField="UserNo" UniqueName="UserNo">
                    <HeaderStyle Width="100px" />
                </telerik:GridBoundColumn>
                <telerik:GridBoundColumn HeaderText="會員名稱"
                    DataField="UserName" UniqueName="UserName">
                    <HeaderStyle Width="100px" />
                    <ItemStyle CssClass="u-name" />
                </telerik:GridBoundColumn>
                <telerik:GridBoundColumn HeaderText="加入日期" DataField="RegDate" 
                 UniqueName="RegDate" DataFormatString="{0:yyyy/MM/dd}">
                    <HeaderStyle Width="100px" />
                </telerik:GridBoundColumn>
                <telerik:GridBoundColumn HeaderText="累積點數"
                    DataField="Points" UniqueName="Points" DataFormatString="{0:N0}">
                    <HeaderStyle Width="100px" />
                    <ItemStyle HorizontalAlign="Right" />
                </telerik:GridBoundColumn>
            </Columns>
        </MasterTableView>
        <AlternatingItemStyle HorizontalAlign="Center" />
        <HeaderStyle HorizontalAlign="Center" />
        <ItemStyle HorizontalAlign="Center" />
        <FilterMenu EnableImageSprites="False">
        </FilterMenu>
        <HeaderContextMenu CssClass="GridContextMenu GridContextMenu_Default">
        </HeaderContextMenu>
        <ClientSettings>
            <DataBinding Location="RadGridAjaxSample.aspx" SelectMethod="GetData">
            </DataBinding>
            <ClientEvents OnDataBinding="dataBinding" OnDataBound="dataBound" />
        </ClientSettings>
    </telerik:RadGrid>
    </form>
</body>
</html>

[說明]

  1. 透過DataBinding指定呼叫RadGridAjaxSample.aspx的GetData WebMethod讀取資料(也可寫成一般ASHX,但要自己由POST內容解析取出分頁、篩選參數,要花點功)
  2. function dataBinding會在AJAX取資料前觸發,在此示範如何帶入額外參數(關鍵字查詢)
  3. function dataBound會在AJAX取回資料並Bind到HTML表格後觸發,在此示範用jQuery將會員名稱欄位出現的關鍵字標為紅字
  4. 要由Client端觸重新查詢的寫法為: $find("RadGrid1").get_masterTableView().rebind();
    ($find是ASP.NET AJAX的Client端函數,Telerik的這套元件仍以ASP.NET AJAX為基礎,到了MVC版本才是以jQuery為底)

 

後端程式RadGridAjaxSample.aspx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using Telerik.Web.UI;
using System.Web.Services;
using System.Drawing;
using System.Reflection;
 
public partial class RadGridAjaxSample : System.Web.UI.Page
{
    //模擬資料物件
    public class SimMemberInfo 
    {
        public string UserNo; //會員編號
        public string UserName; //會員名稱
        public DateTime RegDate; //註冊日期
        public int Points; //累積點數
    }
    //查詢結果,包含資料物件集合(已分頁)以及總筆數
    public class RadGridQueryResult<T>
    {
        public int TotalCount;
        public List<T> Items;
    }
    static List<SimMemberInfo> _SimuDataStore = null;
    //模擬對資料庫進行關鍵字查詢,並依要求分頁及排序
    public static RadGridQueryResult<SimMemberInfo> 
        QuerySimuData(string keywd, int stPos, int count, string sortBy)
    {
        if (_SimuDataStore == null)
        {
            Random rnd = new Random();
            //借用具名顏色名稱來產生隨機資料
            string[] colorNames =typeof(Color)
                .GetProperties(BindingFlags.Static | BindingFlags.Public)
                .Select(o => o.Name).ToArray();
            _SimuDataStore = 
                colorNames
                .Select(cn => new SimMemberInfo()
                {
                    UserNo = string.Format("C{0:00000}", rnd.Next(99999)),
                    UserName = cn,
                    RegDate = DateTime.Today.AddDays(- rnd.Next(1000)),
                    Points = rnd.Next(9999)
                }).ToList();
        }
        //指定關鍵字時,使用Contains()對UserName進行比對
        var q = _SimuDataStore.Where(o => 
            string.IsNullOrEmpty(keywd) || o.UserName.Contains(keywd));
        if (!string.IsNullOrEmpty(sortBy))
        {
            //宣告一個函數可傳回SimMemberInfo之指定屬性值用於依動態欄位排序
            Func<SimMemberInfo, string, string> GetColString =
                (o, c) =>
                {
                    switch(c)
                    {
                        case "UserNo": return o.UserNo;
                        case "UserName": return o.UserName;
                        case "RegDate": return o.RegDate.ToString("yyyyMMdd");
                        case "Points": return o.Points.ToString();
                        default: throw new ArgumentException();
                    }
                };
            //sortBy格式為ColName ASC或ColName DESC
            string[] p = sortBy.Split(' ');
            if (p[1] == "ASC")
                q = q.OrderBy(o => GetColString(o, p[0]));
            else
                q = q.OrderByDescending(o => GetColString(o, p[0]));
        }
        return new RadGridQueryResult<SimMemberInfo>()
        {
            TotalCount = q.Count(),
            Items = q.Skip(stPos).Take(count).ToList()
        };
    }
 
    [WebMethod()]
    public static Dictionary<string, object> GetData(
        //前四個參數是RadGrid制式要求,分別為: 起始筆數、每頁筆數、排序設定、篩選設定
        int startRowIndex, int maximumRows, List<GridSortExpression> sortExpression, 
        List<GridFilterExpression> filterExpression,
        //若前端用args.get_methodArguments()加入額外參數,在此要宣告參數接收
        string keywd)
    {
        Dictionary<string, object> data = new Dictionary<string, object>();
        //取得排序參數(只實做支援單欄排序)
        GridSortExpression gse = sortExpression.FirstOrDefault();
        string sortBy = gse != null ? 
            string.Format("{0} {1}", gse.FieldName, gse.SortOrderAsString()) : "";
        //模擬呼叫資料庫進行查詢(傳入關鍵字、分頁參數及排序欄位)
        var res = QuerySimuData(keywd, startRowIndex, maximumRows, sortBy);
        data.Add("Data", res.Items);
        data.Add("Count", res.TotalCount);
        return data;
    }
 
    protected void Page_Load(object sender, EventArgs e)
    {
    }
}

[說明]

  1. 為了簡化起見,沒動用資料庫,只自訂了SimMemberInfo類別模擬資料物件,並以隨機方式產生模擬資料(我用Color.Red等具名顏色來當作會員名稱,很有創意吧!)
  2. WebMethod GetData要接入int startRowIndex, int maximumRows, List<GridSortExpression> sortExpression, List<GridFilterExpression> filterExpression等參數,傳回經篩選(本範例中未實做)、分好頁、排序過的資料集合,同時要回報總筆數。
  3. GetData的keywd參數是前端function dataBinding()時額外加傳的
  4. QuerySimuData中動了點手腳(透過GetColString函數)實現動態指定排序欄位,這在不同資料來源時玩法不同

以下為執行畫面:

由於配合Telerik元件才能執行,大家不一定能立即在自己的機器上試用,所以我準備了一個線上展示,有興趣的人可以看看。

歡迎推文分享:
Published 01 December 2011 06:07 AM 由 Jeffrey
Filed under: , ,



意見

# 謝謝分享 said on 29 January, 2012 04:16 AM

謝謝分享,每看一篇文章就覺得自己成長了一些@@

這套元件還真貴,雖然蠻強大的 囧

你的看法呢?

(必要的) 
(必要的) 
(選擇性的)
(必要的) 

搜尋

Go

<December 2011>
SunMonTueWedThuFriSat
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567
 
RSS
【工商服務】
OrcsWeb: Windows Server Hosting

Tags 分類檢視
關於作者

一個醉心技術又酷愛分享的Coding魔人,十年的IT職場生涯,寫過系統、管過專案, 也帶過團隊,最後還是無怨無悔地選擇了技術鑽研這條路,近年來則以做一個"有為的中年人"自許。

文章典藏
其他功能

這個部落格


BlogLook Score and Rank

Syndication