Asp.Net伺服器控制項開發的Grid實現(四)回傳事件

來源:互聯網
上載者:User

標籤:回傳事件   ipostbackeventhandle   伺服器控制項   

在使用Grid的時候,會用到連結跳轉。如果只是普通的連結跳轉,那隻要使用a標籤的href就可以實現。但是有時,我們希望在連結跳轉的時候,能夠引發回傳事件,在後台作出一定的處理,然後再跳轉。這樣要如何?呢?我們可以定義一個LinkButtonField來實現。代碼如下

using System;using System.Collections.Generic;using System.ComponentModel;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Web.UI;namespace AspNetServerControl{    /// <summary>    /// 表格連結按鈕列    /// </summary>    [ToolboxItem(false)]    [ParseChildren(true)]    [PersistChildren(false)]    public class LinkButtonField : BaseField    {    }}

註:LinkButtonField也是繼承自BaseField。添加了一個欄欄位後,我們就需要在列編輯器中,增加相應的類型,代碼如下:

    [Designer("AspNetServerControl.Design.GridDesigner, AspNetServerControl.Design")]    [ToolboxData("<{0}:Grid Title=\"Grid\" runat=\"server\"><Columns></Columns></{0}:Grid>")]    [ToolboxBitmap(typeof(Grid), "toolbox.Grid.bmp")]    [Description("表格控制項")]    [ParseChildren(true)]    [PersistChildren(false)]    [ControlBuilder(typeof(NotAllowWhitespaceLiteralsBuilder))]    [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]    public class Grid : ControlBase, IPostBackEventHandler    {///屬性代碼請參照《 Asp.Net伺服器控制項開發的Grid實現(二)Html標記渲染》#region 事件        #region OnRowCommand        //// Defines the Click event.        //public event EventHandler<GridCommandEventArgs> RowCommand;        ////Invoke delegates registered with the Click event.        //protected virtual void OnRowCommand(GridCommandEventArgs e)        //{        //    if (RowCommand != null)        //    {        //        RowCommand(this, e);        //    }        //}        private static readonly object _rowCommandHandlerKey = new object();        /// <summary>        /// 行內事件        /// </summary>        [Category(CategoryName.ACTION)]        [Description("行內事件")]        public event EventHandler<GridCommandEventArgs> RowCommand        {            add            {                Events.AddHandler(_rowCommandHandlerKey, value);            }            remove            {                Events.RemoveHandler(_rowCommandHandlerKey, value);            }        }        /// <summary>        /// 觸發行內事件        /// </summary>        /// <param name="e">事件參數</param>        protected virtual void OnRowCommand(GridCommandEventArgs e)        {            EventHandler<GridCommandEventArgs> handler = Events[_rowCommandHandlerKey] as EventHandler<GridCommandEventArgs>;            if (handler != null)            {                handler(this, e);            }        }        #endregion        #endregion protected override void Render(HtmlTextWriter writer)        {            base.Render(writer);            if (_columns == null)            {                return;            }            writer.Write(                String.Format("<table id=\"{0}\" name=\"{1}\" rules=\"all\" border=\"1\" cellspacing=\"0\" style=\"width:100%;border-collapse:collapse;\">", UniqueID, UniqueID));            //RenderHeader(writer);            RenderBody(writer);            writer.Write("</table>");        }        private void RenderBody(HtmlTextWriter writer)        {            DataTable dt = DataSource as DataTable;            if (dt == null || dt.Rows.Count <= 0)            {                return;            }            writer.Write("<tbody>");            int rowIndex = 0;            int columnIndex = 0;            foreach (DataRow row in dt.Rows)            {                writer.Write(String.Format("<tr {0}>", GetRowStyle()));                columnIndex = 0;                foreach (GridColumn column in Columns)                {                    if (column is LinkButtonField)                    {                        writer.Write(String.Format("<td  {0}><a {1} name=\"{2}\">{3}</a></td>",                                                    GetItemStyle(column),                                                    GetLinkButtonPostBack(column as LinkButtonField, rowIndex, columnIndex),                                                    column.UniqueID,                                                    row[column.DataField]));                    }                    else                    {                        writer.Write(String.Format("<td  {0}>{1}</td>", GetItemStyle(column), row[column.DataField]));                    }                    columnIndex++;                }                writer.Write("</tr>");                rowIndex++;            }            writer.Write("</tbody>");        }        private String GetLinkButtonPostBack(LinkButtonField linkButton, int rowIndex, int columnIndex)        {            if (linkButton == null)            {                return "";            }            String arg = String.Format("Command${0}${1}${2}${3}", rowIndex, columnIndex, linkButton.CommandName, linkButton.CommandArgument);            String clientScript = Page.ClientScript.GetPostBackClientHyperlink(this, arg);            String href = String.Format("href=\"{0}\"", clientScript);            return href;        }///其他代碼請參照《 Asp.Net伺服器控制項開發的Grid實現(二)Html標記渲染》      public void RaisePostBackEvent(string eventArgument)        {            if (eventArgument.StartsWith("Command$"))            {                string[] commandArgs = eventArgument.Split('$');                if (commandArgs.Length == 5)                {                    GridCommandEventArgs gridCommandEventArgs =                        new GridCommandEventArgs(Convert.ToInt32(commandArgs[1]),                                                 Convert.ToInt32(commandArgs[2]),                                                 commandArgs[3],                                                 commandArgs[4]);                    OnRowCommand(gridCommandEventArgs);                }            }        }


註:

1.IPostBackEventHandler介面需要實現RaisePostBackEvent方法。

2.在頁面回傳時,是通過控制項的name來索引到對應的事件,然後回傳到目標的。所以對於Grid控制項,我們必須要在Render的時候將name賦值,然後在產生回傳指令碼時將其對應上。

(1)所以在Render函數的table標記的name要賦值,這裡使用UniqueID以確保唯一性。

(2)同時在RenderBody時,如果是LinkButtonField的列,就增加回傳指令碼。即將LinkButtonField渲染到表格的單元格中時,使用a標記渲染,同時將其href賦值相應的指令碼。在GetLinkButtonPostBack中產生相應的回傳指令碼。

(3)GetLinkButtonPostBack函數中,將單元格的列索引和行索引以及LinkButtonField的CommandName和CommandArgument一同作為回傳參數。同時,為了便於區分,使用Command作為首碼,並以$作為參數間的分隔字元。使用Page.ClientScript.GetPostBackClientHyperlink來產生回傳的js指令碼,使用該系統方法相應簡單,當然也可以直接寫出指令碼,代碼如下。

javascript:__doPostBack('Grid_Edit','Command$0$3$LINK$cmdarg'

3.在RaisePostBackEvent收到回傳事件後,將相應的參數分離出來,並作相應的處理。為了參夠讓使用Grid自訂回傳後調用的事件,我們自訂了一個OnRowCommand事件。

4.OnRowCommand事件由三個部分主成。

(1)唯一KEY:使用靜態唯讀object,即_rowCommandHandlerKey。

(2)將事件添加到委託事件的處理列表中,即RowCommand中。也有直接使用委託來定義的,但效能上不及這種定義。委託直接定義的,原則上是安全執行緒些。為了能夠更好的自訂事件,我們定義了一個事件參數GridCommandEventArgs。代碼見後文。

(3)使用Grid的開發人員實現的OnRowCommand事件,相當於是按鈕的OnClick事件。注意,此事件的命名必須與前面的委託相對應,即只在前面增加一個On。

GridCommandEventArgs

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace AspNetServerControl{    /// <summary>    /// 表格行命令事件參數    /// </summary>    public class GridCommandEventArgs : EventArgs    {        private int _rowIndex;        /// <summary>        /// 行索引        /// </summary>        public int RowIndex        {            get { return _rowIndex; }            set { _rowIndex = value; }        }        private int _columnIndex;        /// <summary>        /// 列索引        /// </summary>        public int ColumnIndex        {            get { return _columnIndex; }            set { _columnIndex = value; }        }        private string _commandName;        /// <summary>        /// 命令名稱        /// </summary>        public string CommandName        {            get { return _commandName; }            set { _commandName = value; }        }        private string _commandArgument;        /// <summary>        /// 命令參數        /// </summary>        public string CommandArgument        {            get { return _commandArgument; }            set { _commandArgument = value; }        }        /// <summary>        /// 建構函式        /// </summary>        /// <param name="rowIndex">行索引</param>        /// <param name="columnIndex">列索引</param>        /// <param name="commandName">命令名稱</param>        /// <param name="commandArgument">命令參數</param>        public GridCommandEventArgs(int rowIndex, int columnIndex, string commandName, string commandArgument)        {            _rowIndex = rowIndex;            _columnIndex = columnIndex;            _commandName = commandName;            _commandArgument = commandArgument;        }    }}

在完成這些後,就可以使用了。

UI代碼如下:

 <div>            <S:Grid runat="server" ID="Grid_Edit" OnRowCommand="Grid_Edit_RowCommand">                <RowStyle Height="50px;" />                <Columns>                    <S:BoundField runat="server" ID="BoundField1" HeaderText="貨號" DataField="NO">                        <ItemStyle HorizontalAlign="Center" />                    </S:BoundField>                    <S:BoundField runat="server" ID="BoundField2" HeaderText="類型" DataField="Type">                        <ItemStyle HorizontalAlign="Center" />                    </S:BoundField>                    <S:BoundField runat="server" ID="BoundField3" HeaderText="狀態" DataField="Status">                        <ItemStyle HorizontalAlign="Center" />                    </S:BoundField>                    <S:LinkButtonField runat="server" ID="LinkButtonField1" HeaderText="連結"                        DataField="Link"                        CommandName="LINK">                    </S:LinkButtonField>                </Columns>            </S:Grid>        </div>

對應的後台代碼如下:

      private void InitLoad()        {            Grid_Edit.DataSource = GenerateData();                    }        private DataTable GenerateData()        {            DataTable dt = new DataTable();            dt.Columns.Add("NO");            dt.Columns.Add("Type");            dt.Columns.Add("Status");            dt.Columns.Add("Link");            dt.Rows.Add(new String[] { "H10001", "食品", "已售完", "http://www.baidu.com" });            dt.Rows.Add(new String[] { "H10002", "蔬菜", "待銷售", "http://www.baidu.com" });            dt.Rows.Add(new String[] { "H10003", "水果", "待銷售", "http://www.baidu.com" });            dt.Rows.Add(new String[] { "H10004", "器具", "銷售中", "http://www.baidu.com" });            return dt;        }        protected void Grid_Edit_RowCommand(object sender, AspNetServerControl.GridCommandEventArgs e)        {            //需要處理的代碼        }
這樣Grid的回傳事件就是實現了。其他的回傳處理,可以仿此。




Asp.Net伺服器控制項開發的Grid實現(四)回傳事件

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.