Today I am very very happy because i learned new concepts like events/ Custom event argument/delegate / ICallbackEventHandler/ How to set default prefix to the user control ex: instead of cc:Control i will use my own prefix like "asp" asp:Control/ How to create nested properties to the control.
Now i will explain how to create "Callback" Control using "ICallbackEventHandler" and Custom Control .
1. Need to Create library project Name as "CallbackCtrlLib" and Create one class called "Callback" and inherit "Callback" from the "WebControl, System.Web.UI.ICallbackEventHandler" to achieve callback functionality.
2. How to set default prefix to the custom/user/web user control
Ans: In general if we are not specify any prefix to the custom/user/web user control it will take "cc" as default prefix whenever your drag and drop the particular user control in the page it will shows like this
<cc:Callback ID="Callback1" runat="server" />
But i want to change the default prefix "cc" to my own prefix like "asp" or any thing you want. To achieve this one we need to include the following line before the name space of the custom/web user control.
[
assembly:
TagPrefix(
"CallbackCtrlLib",
"asp")]
Here first argument of "TagPrefix" will expect name space of the control and second argument will be prefix name of the user control. Here "CallbackCtrlLib" is the name space of the Callback Control and "asp" is the my control prefix name it can be anything.
3. How to Create Nested properties to the Control/describing asp.net control properties declaratively
Ans: I want to create nested properties to the user control to create different clientside events
To achieve above thing we need to do the following things:
A) We need to use [ParseChildren(true)] and [PersistChildren(true)] in the top of the class to achieve nested properties
B) First we need to create "ClientSideEvents " as class and we need to use that "ClientSideEvents " as property return datatype.
Ex:
==
public class ClientSideEvents
{
private string _endCallback;
private string _callbackError;
private string _callbackcomplete;
public string CallbackError
{
get { return _callbackError; }
set { _callbackError = value; }
}
public string EndCallback
{
get { return _endCallback; }
set { _endCallback = value; }
}
public string CallbackComplete
{
get { return _callbackcomplete; }
set { _callbackcomplete = value; }
}
}
"ClientSideEvents " will contains 3 properties 1) CallbackError 2) EndCallback 3) CallbackComplete
C) We need to create "ClientSideEvents " property . And nee to use [PersistenceMode(PersistenceMode.InnerProperty)] and [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] as the top of the property.
Ex:
==
private ClientSideEvents _clientSideEvents;
[PersistenceMode(PersistenceMode.InnerProperty)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public ClientSideEvents ClientSideEvents
{
get
{
if (_clientSideEvents == null)
_clientSideEvents = new ClientSideEvents();
return _clientSideEvents;
}
}
4. Now we need to create delegates and events for the User/Web control to handle custom callback
A) Need to create custom event argument class to pass custom event args to the event handler. Here i am passing "Parameter"" and "Result" are the custom arguments to the "CustomCallback" event.
ex:
==
public class CallbackEventArgs:EventArgs
{
public String Parameter {get;set;}
public String Result {get;set;}
}
B) Need to write a function which is reference to an event called "CustomCallback". if "CustomCallback" is not null means user provided/implemented event logic to the user control in the page so we need invoke/execute the event otherwise no need to execute/invoke event.
ex:
==
public delegate void EventHandler(Object obj, CallbackEventArgs e);
public event EventHandler CustomCallback;
private string _clientInstanceName;
protected void OnCustomCallback()
{
if (CustomCallback != null)
{
CustomCallback(this, new CallbackEventArgs());
}
}
5) Need to create one "div" element which will play key role in the "Callback" control. We need to override "Render" event in that we need to create "div" element.
Ex:
==
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
protected override void Render(HtmlTextWriter writer)
{
writer.Write("<div id=\"" + (ClientInstanceName !=null ? ClientInstanceName : this.ID) + "\"></div>");
}
Here "ClientInstanceName " is the property of the user control. User can perform call back using ClientinstanceName or User Control ID.
6) Now we need to implement "RaiseCallbackEvent" of ICallbackEventHandler. Here we will customize "RaiseCallbackEvent" with our custom events. Here i will invoke/Execute OnCustomCallback" of the user control. As i mentioned in the above i will pass custom event arguments to the "CustomCallback" event. Here i will assign "CallbackEventArgs " Parameter value with "eventArgument". I will use it in the "OnCustomCallback" event of the user control and from there i will return "CallbackEventArgs " "Result" value.
Ex:
==
CallbackEventArgs objCallbackEvtargs = new CallbackEventArgs();
public void RaiseCallbackEvent(String eventArgument)
{
try
{
if (CustomCallback != null)
{
objCallbackEvtargs.Parameter = eventArgument;
CustomCallback(this, objCallbackEvtargs);
}
}
catch { throw; }
}
7) Now we need to implement "GetCallbackResult()" of ICallbackEventHandler. I will return the "CustomCallback" event argument "Result" value to the user.
Ex:
==
public String GetCallbackResult()
{
return objCallbackEvtargs.Result;
}
8) Now final and very tricky logic. Here we need to get callback reference of the control and need to add it to the page during override of "OnLoad" event. And also we need to implement some client side methods like "element.PerformCallback()". Implementation of clientside events is done with the help of "jquery" and "Ajax Javascript Framework" like "Sys.Application" namespace. This "Sys.Application" will work only when "ScriptManager" presents in the Masterpage/Page otherwise it will throw "Sys.Application" undefined javascript error.
Ex:
==
protected override void OnLoad(EventArgs e)
{
if (CustomCallback != null)
{
String cbReference = Page.ClientScript.GetCallbackEventReference(this, "parm", (CustomCallback != null ? (ClientSideEvents.CallbackComplete != null ? ClientSideEvents.CallbackComplete : "ReceiveServerData") : "null"), "this", this.ClientSideEvents.CallbackError, false);
Page.ClientScript.RegisterStartupScript(this.GetType(),
"AttachCallbackEvent", "function AttachCallbackEvent(src,callbackId,callbackScript){Sys.Application.add_init(function () { myObj = {PerformCallback: function (parm) { eval(callbackScript); }}; $.extend($get(src), myObj);});}", true);
Page.ClientScript.RegisterStartupScript(this.GetType(), this.ID + "_" + "AttachCallbackEvent", "AttachCallbackEvent(\"" + (ClientInstanceName != null ? ClientInstanceName : this.ID) + "\",\"" + this.UniqueID + "\",\"" + cbReference + "\");", true);
}
base.OnLoad(e);
}
Here i have one common javascript function "AttachCallbackEvent" which is common to attach clientside callback events to elements. "AttachCallbackEvent" will expect clientinstancename or ID of the user control as "src" and User Control Callback Reference script as "callbackScript" and User Control unique id as "callbackId". "callbackId" is not used.
During the "User Control Callback Reference" generation i am checking that if any clientside events. If any thing is defined then i am taking that events else i am using default clientside events.
Here "PerformCallback" clientside function will be attached based on the "Src" parameter. During the "PerformCallback" i am executing "User Control Callback Reference" script.
Here i am checking if " if (CustomCallback != null)" then only i am attaching callback events otherwise i am not doing because i am doing all the operation based on the "OnCustomCallback" event.
Complete Example with Working Code : Download
Finally i am very very thanks to
References:
========
Callback Example:
=================
http://msdn.microsoft.com/en-us/library/ms178210(v=vs.100).aspx
How to create Custom Control Properties Declaratively like dropdownlist items:
=============================================================
http://www.robertwray.co.uk/blog/2008/02/describing-aspnet-control-properties-declaratively.html
Set Default Prefix of custom Control
====================================
http://msdn.microsoft.com/en-us/library/system.web.ui.tagprefixattribute.tagprefixattribute.aspx