Welcome to MSDN Blogs Sign in | Join | Help

SYSK 331: How To Expose A Client-Side Event From Your ASP.NET Control

Consider the following scenario – you create your own calendar control and you’d like to raise an event when a date is selected (e.g. OnDateClicked)… and you’d like for the users of your calendar control to process the event using JavaScript on the client (or think of any other scenario of when a custom client-side event would be useful).

 

There are plenty samples on how to fire a server-side event, but none that I can find on how to raise one on the client.  The code below shows how to make it happen…

 

1.    Implement System.Web.UI.IScriptControl interface

 

using System;

using System.Data;

using System.Configuration;

using System.Web;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Web.UI.HtmlControls;

 

[assembly: System.Web.UI.WebResource("MyTableCtrl.Scripts.MyTable.js", "text/javascript")]

namespace MyControls

{

    public class MyTable : System.Web.UI.HtmlControls.HtmlTable, System.Web.UI.IScriptControl

    {

        private string _cellClickedDelegate;

 

        public MyTable()

        {

            base.Border = 1;

 

            for (int i = 0; i < 5; i++)

            {

                HtmlTableRow tr = new HtmlTableRow();

 

                for (int j = 0; j < 3; j++)

                {

                    HtmlTableCell td = new HtmlTableCell();

                    td.InnerHtml = string.Format("&nbsp;{0}.{1}&nbsp;", i + 1, j + 1);

                    td.Style["cursor"] = "hand";

                    tr.Cells.Add(td);

                }

 

                base.Rows.Add(tr);

            }

        }

 

        protected override void OnPreRender(EventArgs e)

        {

            if (this.DesignMode == false)

            {

                ScriptManager sm = ScriptManager.GetCurrent(this.Page);

                if (sm != null)

                    sm.RegisterScriptControl(this);

            }

 

            base.OnPreRender(e);

        }

 

        protected override void Render(HtmlTextWriter writer)

        {

            if (this.DesignMode == false)

            {

                ScriptManager sm = ScriptManager.GetCurrent(this.Page);

                if (sm != null)

                    sm.RegisterScriptDescriptors(this);

            }

 

            base.Render(writer);

        }

 

       

 

        #region IScriptControl Members

 

        // Expose client side property for the cellClicked event

        public string cellClicked

        {

            get { return _cellClickedDelegate; }

            set { _cellClickedDelegate = value; }

        }

 

        public System.Collections.Generic.IEnumerable<ScriptDescriptor> GetScriptDescriptors()

        {

            System.Collections.Generic.IEnumerable<ScriptDescriptor> result = null;

 

            if (string.IsNullOrEmpty(_cellClickedDelegate))

            {

                result = new ScriptDescriptor[] { };

            }

            else

            {

                ScriptControlDescriptor descriptor = new ScriptControlDescriptor(this.GetType().FullName, this.ClientID);

                descriptor.AddEvent("cellClicked", _cellClickedDelegate);

 

                result = new ScriptDescriptor[] { descriptor };

            }

 

            return result;

        }

 

        public System.Collections.Generic.IEnumerable<ScriptReference> GetScriptReferences()

        {

            return new ScriptReference[] { new ScriptReference("MyTableCtrl.Scripts.MyTable.js", System.Reflection.Assembly.GetAssembly(this.GetType()).FullName) };

        }

 

        #endregion

    }

}

 

 

2.    Implement event subscription and firing in a JavaScript file (e.g. Scripts\MyTable.js)

 

Type.registerNamespace("MyControls");

 

MyControls.MyTable = function(element)

{

    MyControls.MyTable.initializeBase(this, [element]);    

}

 

MyControls.MyTable.prototype =

{   

    initialize: function()

    {   

        MyControls.MyTable.callBaseMethod(this, 'initialize');

       

        $addHandlers(this.get_element(), { 'click':this._onCellClicked }, this);

    },

    add_cellClicked : function(handler)

    {

        this.get_events().addHandler("cellClicked", handler);

    },

    remove_cellClicked : function(handler)

    {

        this.get_events().removeHandler("cellClicked", handler);

    },

    _onCellClicked: function(source, e)

    {

        if (!this._events) return;

        var handler = this._events.getHandler("cellClicked");

        if (handler)

            handler(source.rawEvent.srcElement);

    },

    dispose: function()

    {     

        $clearHandlers(this.get_element());               

 

        MyControls.MyTable.callBaseMethod(this, 'dispose');

    }

}

 

MyControls.MyTable.registerClass("MyControls.MyTable", Sys.UI.Control);

 

 

 

3.    Subscribe for the event

 

<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>

 

<%@ Register Assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"

    Namespace="System.Web.UI" TagPrefix="asp" %>

<%@ Register Assembly="MyTableCtrl" Namespace="MyControls" TagPrefix="cc" %>

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

 

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server">

    <title>Untitled Page</title>   

</head>

<body>   

    <form id="form1" runat="server">

        <asp:ScriptManager ID="ScriptManager1" runat="server" >

        </asp:ScriptManager>

     

        <cc:MyTable runat="server" id="table1" cellClicked="OnCellClicked"></cc:MyTable>

    </form>

   

    <script type="text/javascript">       

        function OnCellClicked(cell)

        {

            alert("OnCellClicked: " + cell.innerText);

        }

    </script>

</body>

</html>

 

 

 

Published Wednesday, April 18, 2007 5:02 AM by irenak

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# links for 2007-04-19 &raquo; mhinze.com

Thursday, April 19, 2007 11:24 AM by links for 2007-04-19 » mhinze.com

Leave a Comment

(required) 
required 
(required) 
 
Page view tracker