当前位置: 移动技术网 > IT编程>开发语言>.net > Asp.Net服务器控件开发的Grid实现(四)回发事件

Asp.Net服务器控件开发的Grid实现(四)回发事件

2018年03月10日  | 移动技术网IT编程  | 我要评论

城市房屋拆迁管理条例,dat是什么格式,梦田折纸学院

在使用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
{
    /// 
    /// 表格链接按钮列
    /// 
    [ToolboxItem(false)]
    [ParseChildren(true)]
    [PersistChildren(false)]
    public class LinkButtonField : BaseField
    {

    }
}

注:LinkButtonField也是继承自BaseField。添加了一个列字段后,我们就需要在列编辑器中,增加相应的类型,代码如下:

    [Designer("AspNetServerControl.Design.GridDesigner, AspNetServerControl.Design")]
    [ToolboxData("")]
    [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 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();

        /// 
        /// 行内事件
        /// 
        [Category(CategoryName.ACTION)]
        [Description("行内事件")]
        public event EventHandler RowCommand
        {
            add
            {
                Events.AddHandler(_rowCommandHandlerKey, value);
            }
            remove
            {
                Events.RemoveHandler(_rowCommandHandlerKey, value);
            }
        }

        /// 
        /// 触发行内事件
        /// 
        /// 事件参数
        protected virtual void OnRowCommand(GridCommandEventArgs e)
        {
            EventHandler handler = Events[_rowCommandHandlerKey] as EventHandler;
            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("", UniqueID, UniqueID));
            //RenderHeader(writer);
            RenderBody(writer);
            writer.Write("");
        }

        private void RenderBody(HtmlTextWriter writer)
        {
            DataTable dt = DataSource as DataTable;
            if (dt == null || dt.Rows.Count ");
            int rowIndex = 0;
            int columnIndex = 0;
            foreach (DataRow row in dt.Rows)
            {
                writer.Write(String.Format("", GetRowStyle()));
                columnIndex = 0;
                foreach (GridColumn column in Columns)
                {
                    if (column is LinkButtonField)
                    {
                        writer.Write(String.Format("{3}",
                                                    GetItemStyle(column),
                                                    GetLinkButtonPostBack(column as LinkButtonField, rowIndex, columnIndex),
                                                    column.UniqueID,
                                                    row[column.DataField]));
                    }
                    else
                    {
                        writer.Write(String.Format("{1}", GetItemStyle(column), row[column.DataField]));
                    }
                    columnIndex++;
                }
                writer.Write("");
                rowIndex++;
            }
            writer.Write("");
        }

        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
{
    /// 
    /// 表格行命令事件参数
    /// 
    public class GridCommandEventArgs : EventArgs
    {

        private int _rowIndex;

        /// 
        /// 行索引
        /// 
        public int RowIndex
        {
            get { return _rowIndex; }
            set { _rowIndex = value; }
        }

        private int _columnIndex;

        /// 
        /// 列索引
        /// 
        public int ColumnIndex
        {
            get { return _columnIndex; }
            set { _columnIndex = value; }
        }


        private string _commandName;

        /// 
        /// 命令名称
        /// 
        public string CommandName
        {
            get { return _commandName; }
            set { _commandName = value; }
        }


        private string _commandArgument;

        /// 
        /// 命令参数
        /// 
        public string CommandArgument
        {
            get { return _commandArgument; }
            set { _commandArgument = value; }
        }


        /// 
        /// 构造函数
        /// 
        /// 行索引
        /// 列索引
        /// 命令名称
        /// 命令参数
        public GridCommandEventArgs(int rowIndex, int columnIndex, string commandName, string commandArgument)
        {
            _rowIndex = rowIndex;
            _columnIndex = columnIndex;
            _commandName = commandName;
            _commandArgument = commandArgument;
        }

    }
}

在完成这些后,就可以使用了。

UI代码如下:

 


对应的后台代码如下:

      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", "食品", "已售完", "https://www.baidu.com" });
            dt.Rows.Add(new String[] { "H10002", "蔬菜", "待销售", "https://www.baidu.com" });
            dt.Rows.Add(new String[] { "H10003", "水果", "待销售", "https://www.baidu.com" });
            dt.Rows.Add(new String[] { "H10004", "器具", "销售中", "https://www.baidu.com" });

            return dt;
        }

        protected void Grid_Edit_RowCommand(object sender, AspNetServerControl.GridCommandEventArgs e)
        {
            //需要处理的代码
        }
这样Grid的回发事件就是实现了。其他的回发处理,可以仿此。




如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网