
Creating the Web Server Control
A Web server control that includes client features by using ASP.NET AJAX functionality is like any other Web server control. However, the control also implements the IScriptControl interface from the System.Web.UI namespace. The control in this topic extends the ASP.NET TextBox control by inheriting the TextBox class and implementing the IScriptControl interface.
The following example shows the class definition.
Public Class SampleTextBox
Inherits TextBox
Implements IScriptControl
public class SampleTextBox : TextBox, IScriptControl
The new Web server control includes two properties that are used to implement the client requirements:
HighlightCssClass, which identifies the CSS class that will be applied to the DOM element to highlight the control when it has focus.
NoHighlightCssClass, which identifies the CSS class that will be applied to the DOM element when it does not have focus.
Implementing the IScriptControl Interface
The following table lists members of the IScriptControl interface that you must implement in a Web server control.
- GetScriptDescriptors
Returns a collection of ScriptDescriptor objects that contain information about instances of client components that are used with the Web server control. This includes the client type to create, the properties to assign, and the events to add handlers for.
- GetScriptReferences
Returns a collection of ScriptReference objects that contain information about the client-script libraries to be included with the control. The client-script libraries define the client types and any other JavaScript code that is required for the behavior.
The Web server control in this topic uses the GetScriptDescriptors method to define the instance of the client control type. The control creates a new ScriptControlDescriptor object (the ScriptControlDescriptor class derives from the ScriptDescriptor class) and includes the object in the return value for the GetScriptDescriptors method.
The ScriptControlDescriptor object includes the name of the client class (Samples.SampleTextBox) and the ClientID value for the Web server control. This value is used as the id value for the rendered DOM element. The client class name and the ClientID property values are passed to the constructor for the ScriptControlDescriptor object.
The ScriptControlDescriptor class is used to set the client control's property values, which are obtained from properties of the Web server control. To define the client control's properties, the Web server control uses the ScriptComponentDescriptor..::.AddProperty method of the ScriptControlDescriptor class. The Web server control then specifies a name and value for the property of the client control, based on the corresponding property of the Web server control. This example uses a ScriptControlDescriptor object to set the values of the highlightCssClass and nohighlightCssClass properties in the client control.
The Web server control supplies the ScriptControlDescriptor object in the return value for the GetScriptDescriptors method. Therefore, whenever the Web server control is rendered to the browser, ASP.NET renders JavaScript that creates an instance of the client control with all defined properties and event handlers. The control instance is attached to the DOM element, based on the ClientID property that is rendered from the Web server control. The following example shows declarative ASP.NET markup that includes the Web server control from this topic in a page.
<sample:SampleTextBox runat="server"
ID="SampleTextBox1"
HighlightCssClass="MyHighLight"
NoHighlightCssClass="MyLowLight" />
The rendered output of the page includes a call to the $create method that identifies the client class to create. It also provides values for the client properties and the id value of the DOM object that the client control is associated with. The following example shows a rendered $create method.
$create(Samples.SampleTextBox, {"highlightCssClass":"MyHighLight","nohighlightCssClass":"MyLowLight"}, null, null, $get('SampleTextBox1'));
The example Web server control uses the GetScriptReferences method to pass the location of the script library that defines the client control type. In this example, this is a URL to the script file named SampleTextBox.js, which you will create later. The reference is made by creating a new ScriptReference object, and by then setting the Path property to the URL of the file that contains the client code.
The following example shows the implementations of the GetScriptDescriptors and GetScriptReferences methods.
Protected Overridable Function GetScriptReferences() As IEnumerable(Of ScriptReference)
Dim reference As ScriptReference = New ScriptReference()
reference.Path = ResolveClientUrl("SampleTextBox.js")
Return New ScriptReference() {reference}
End Function
Protected Overridable Function GetScriptDescriptors() As IEnumerable(Of ScriptDescriptor)
Dim descriptor As ScriptControlDescriptor = New ScriptControlDescriptor("Samples.SampleTextBox", Me.ClientID)
descriptor.AddProperty("highlightCssClass", Me.HighlightCssClass)
descriptor.AddProperty("nohighlightCssClass", Me.NoHighlightCssClass)
Return New ScriptDescriptor() {descriptor}
End Function
Function IScriptControlGetScriptReferences() As IEnumerable(Of ScriptReference) Implements IScriptControl.GetScriptReferences
Return GetScriptReferences()
End Function
Function IScriptControlGetScriptDescriptors() As IEnumerable(Of ScriptDescriptor) Implements IScriptControl.GetScriptDescriptors
Return GetScriptDescriptors()
End Function
protected virtual IEnumerable<ScriptReference> GetScriptReferences()
{
ScriptReference reference = new ScriptReference();
reference.Path = ResolveClientUrl("SampleTextBox.js");
return new ScriptReference[] { reference };
}
protected virtual IEnumerable<ScriptDescriptor> GetScriptDescriptors()
{
ScriptControlDescriptor descriptor = new ScriptControlDescriptor("Samples.SampleTextBox", this.ClientID);
descriptor.AddProperty("highlightCssClass", this.HighlightCssClass);
descriptor.AddProperty("nohighlightCssClass", this.NoHighlightCssClass);
return new ScriptDescriptor[] { descriptor };
}
IEnumerable<ScriptReference> IScriptControl.GetScriptReferences()
{
return GetScriptReferences();
}
IEnumerable<ScriptDescriptor> IScriptControl.GetScriptDescriptors()
{
return GetScriptDescriptors();
}
Registering the Client Control
Client controls must be registered with the ScriptManager object for the current page. This is accomplished by calling the RegisterScriptControl<(Of <(TScriptControl>)>) method of the ScriptManager class and supplying a reference to the client control.
The example Web server control registers itself as a client control with the ScriptManager control on the page. To do this, the control overrides the OnPreRender method of the base TextBox control. It then calls the RegisterScriptControl()()() method to register itself as a client control. Additionally, the control registers the script descriptors that are created by the GetScriptDescriptors method. It does so by calling the RegisterScriptDescriptors()()() method in the control's Render method.
The following example shows the calls to the RegisterScriptControl()()() and RegisterScriptDescriptors()()() methods.
Protected Overrides Sub OnPreRender(ByVal e As EventArgs)
If Not Me.DesignMode Then
' Test for ScriptManager and register if it exists
sm = ScriptManager.GetCurrent(Page)
If sm Is Nothing Then _
Throw New HttpException("A ScriptManager control must exist on the current page.")
sm.RegisterScriptControl(Me)
End If
MyBase.OnPreRender(e)
End Sub
Protected Overrides Sub Render(ByVal writer As HtmlTextWriter)
If Not Me.DesignMode Then _
sm.RegisterScriptDescriptors(Me)
MyBase.Render(writer)
End Sub
protected override void OnPreRender(EventArgs e)
{
if (!this.DesignMode)
{
// Test for ScriptManager and register if it exists
sm = ScriptManager.GetCurrent(Page);
if (sm == null)
throw new HttpException("A ScriptManager control must exist on the current page.");
sm.RegisterScriptControl(this);
}
base.OnPreRender(e);
}
protected override void Render(HtmlTextWriter writer)
{
if (!this.DesignMode)
sm.RegisterScriptDescriptors(this);
base.Render(writer);
}
The following example shows the complete code for the Web server control.
Imports System
Imports System.Data
Imports System.Configuration
Imports System.Web
Imports System.Web.Security
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Web.UI.WebControls.WebParts
Imports System.Web.UI.HtmlControls
Imports System.Collections.Generic
Namespace Samples.VB
Public Class SampleTextBox
Inherits TextBox
Implements IScriptControl
Private _highlightCssClass As String
Private _noHighlightCssClass As String
Private sm As ScriptManager
Public Property HighlightCssClass() As String
Get
Return _highlightCssClass
End Get
Set(ByVal value As String)
_highlightCssClass = value
End Set
End Property
Public Property NoHighlightCssClass() As String
Get
Return _noHighlightCssClass
End Get
Set(ByVal value As String)
_noHighlightCssClass = value
End Set
End Property
Protected Overrides Sub OnPreRender(ByVal e As EventArgs)
If Not Me.DesignMode Then
' Test for ScriptManager and register if it exists
sm = ScriptManager.GetCurrent(Page)
If sm Is Nothing Then _
Throw New HttpException("A ScriptManager control must exist on the current page.")
sm.RegisterScriptControl(Me)
End If
MyBase.OnPreRender(e)
End Sub
Protected Overrides Sub Render(ByVal writer As HtmlTextWriter)
If Not Me.DesignMode Then _
sm.RegisterScriptDescriptors(Me)
MyBase.Render(writer)
End Sub
Protected Overridable Function GetScriptReferences() As IEnumerable(Of ScriptReference)
Dim reference As ScriptReference = New ScriptReference()
reference.Path = ResolveClientUrl("SampleTextBox.js")
Return New ScriptReference() {reference}
End Function
Protected Overridable Function GetScriptDescriptors() As IEnumerable(Of ScriptDescriptor)
Dim descriptor As ScriptControlDescriptor = New ScriptControlDescriptor("Samples.SampleTextBox", Me.ClientID)
descriptor.AddProperty("highlightCssClass", Me.HighlightCssClass)
descriptor.AddProperty("nohighlightCssClass", Me.NoHighlightCssClass)
Return New ScriptDescriptor() {descriptor}
End Function
Function IScriptControlGetScriptReferences() As IEnumerable(Of ScriptReference) Implements IScriptControl.GetScriptReferences
Return GetScriptReferences()
End Function
Function IScriptControlGetScriptDescriptors() As IEnumerable(Of ScriptDescriptor) Implements IScriptControl.GetScriptDescriptors
Return GetScriptDescriptors()
End Function
End Class
End Namespace
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;
using System.Collections.Generic;
namespace Samples.CS
{
public class SampleTextBox : TextBox, IScriptControl
{
private string _highlightCssClass;
private string _noHighlightCssClass;
private ScriptManager sm;
public string HighlightCssClass
{
get { return _highlightCssClass; }
set { _highlightCssClass = value; }
}
public string NoHighlightCssClass
{
get { return _noHighlightCssClass; }
set { _noHighlightCssClass = value; }
}
protected override void OnPreRender(EventArgs e)
{
if (!this.DesignMode)
{
// Test for ScriptManager and register if it exists
sm = ScriptManager.GetCurrent(Page);
if (sm == null)
throw new HttpException("A ScriptManager control must exist on the current page.");
sm.RegisterScriptControl(this);
}
base.OnPreRender(e);
}
protected override void Render(HtmlTextWriter writer)
{
if (!this.DesignMode)
sm.RegisterScriptDescriptors(this);
base.Render(writer);
}
protected virtual IEnumerable<ScriptReference> GetScriptReferences()
{
ScriptReference reference = new ScriptReference();
reference.Path = ResolveClientUrl("SampleTextBox.js");
return new ScriptReference[] { reference };
}
protected virtual IEnumerable<ScriptDescriptor> GetScriptDescriptors()
{
ScriptControlDescriptor descriptor = new ScriptControlDescriptor("Samples.SampleTextBox", this.ClientID);
descriptor.AddProperty("highlightCssClass", this.HighlightCssClass);
descriptor.AddProperty("nohighlightCssClass", this.NoHighlightCssClass);
return new ScriptDescriptor[] { descriptor };
}
IEnumerable<ScriptReference> IScriptControl.GetScriptReferences()
{
return GetScriptReferences();
}
IEnumerable<ScriptDescriptor> IScriptControl.GetScriptDescriptors()
{
return GetScriptDescriptors();
}
}
}