Sys.UI.Behavior - AJAX Extender - Custom Behaviour Control


Sponsored Links

73058_New Scooba® 230 Floor Washing Robot + Free Shipping!

 

Sys.UI.Behavior - AJAX Extender - Custom Behaviour Control

Here we take a look at the Microsoft AJAX Library Sys.UI.Behavior - AJAX Extender - Custom Behaviour Control.

We've already looked at the Sys.Component, Sys.UI.Control and then next AJAX Custom Control. So we started at the Sys.Component which allowed us to create Javascript functionality, Sys.Control which allowed us to create AJAX enabled controls, and then the AJAX Custom Control where we embedded the Javascript into a .dll file to make a custom control which is AJAX enabled. So finally here we're going one stage further and creating a control which inherits from the Sys.Behaviour control.

The Sys.Behaviour control provides a base class to derive from to create AJAX Behaviour Custom Controls which provide functionality for extending HTML controls, rather than existing as actual controls on the page. They extend the behaviour of existing HTML controls on the page, so one usually sets the TargetControlID property which is exposed by the Behaviour control which sets which specific DOM control on the page to target and apply the additional behaviour to.

Sys.UI.Behavior - AJAX Extender - Custom Behaviour Control

So continuing the previous examples, I wanted to have an AJAX Behaviour custom control which extends TextBoxes so that they are highlighted when the user has put the focus into that textbox.

So first up, I created a new class library project in Visual Studio, followed by creating 3 files, 1 C#, 1 Javascript and 1 CSS file:


HighLightTextBox.cs
HighLightTextBox.js
highlighttextbox.css


Since the last example, AJAX Custom Control, I've made some changes to get this working as an AJAX Behaviour Extender Custom Control instead of just an AJAX Custom Control, and I've made some slight enhancements, most noticably was the inclusion of a .css file embedded as a resource so it comes packaged with the custom control.

Embed .CSS file as a Resource in a Custom Control

To add a .css file to be embedded as a resource, I first had to add the file to the project, and then in the properties tab in Visual Studio, I selected the 'Build Action' to be Embedded Resource so it will be embedded into the .dll file. Next in the C# class file for my custom control, I had to override the OnInit event, where I used the Page.ClientScript.GetWebResourceUrl() method to generate a pathway to the embedded .css file when it's in the .dll file. I used this method to build a link to the .css file, and then I registered the link to the .css file to be written out into the HTML of the page where the custom control is to be used, by using the ClientScript.RegisterClientScriptBlock() method. Finally I marked the class with the [assembly: WebResource] attribute, which points to the location of the .css file:


[assembly: WebResource("MyNameSpace.highlighttextbox.css", "text/css")]


Here's the small .css file:


.textBoxFocus
{
    background-color:#FFFFF0;
    border: solid blue 2px;
}


Here is how the .css file gets referenced once the page HTML is produced:


<link href="/WebResource.axd?d=9-fatqQDBT30jfa5_uskLJAXOoRTpE_Z2Q_tFjal8gJ6xXrA11a6mxwXbTk9MqRfZ_9mBm91_KLfSluD-aDR5nTWWOXBvMfsJh-jRX1GDwRAcBeF8uLVSUvlX2Pniso3JCtokUnG9gsvVRpY5P4FSw2&t=634771252632353133" type="text/css" rel="stylesheet" />


In the C# sample below, you'll see the whole code required to export the css as an embedded resource inside the OnInit override, plus changes since the AJAX Custom Control example which modify the class to act as a Behaviour. First of all the class needs to inherit from the ExtenderControl class. The class itself needs to be marked with the [TargetControlType] attribute, passing Control as the type of control which this class can extend. Implementing the ExtenderControl means implementing the methods GetScriptDescriptors() and GetScriptReferences(). These methods are described here: AJAX Custom Control.

Here's the full C# class:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI;

[assembly: WebResource("MyNameSpace.highlighttextbox.css", "text/css")]
namespace MyNameSpace
{
    [TargetControlType(typeof(Control))]
    public class HighLightTextBox : ExtenderControl
    {

        protected override IEnumerable GetScriptReferences()
        {
            ScriptReference reference = new ScriptReference();
            //reference.Path = ResolveClientUrl("FocusBehavior.js");
            reference.Assembly = "MyNameSpace";
            reference.Name = "MyNameSpace.HighLightTextBox.js";

            return new ScriptReference[] { reference };
        }

        protected override IEnumerable GetScriptDescriptors(Control targetControl)
        {
            ScriptBehaviorDescriptor descriptor = new ScriptBehaviorDescriptor("MyNameSpace.HighLightTextBox", targetControl.ClientID);

            return new ScriptDescriptor[] { descriptor };
        }

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);

            String css = "<link href=\"" + Page.ClientScript.GetWebResourceUrl(this.GetType(), "MyNameSpace.highlighttextbox.css") + "\" type=\"text/css\" rel=\"stylesheet\" />";

            Page page = this.Page;

            page.ClientScript.RegisterClientScriptBlock(this.GetType(), "cssFile", css, false);
        }
    }
}


I've tried to keep it quite simple and short as possible whilst still acting as a decent custom control. So next up we have the Javascript file, where we inherit our class from the Sys.UI.Behaviour class and provide event handlers for the focus and blur events of a control:


// Register the namespace for the control.
Type.registerNamespace('MyNameSpace');


// Define the behavior properties.
MyNameSpace.HighLightTextBox = function (element) {
    MyNameSpace.HighLightTextBox.initializeBase(this, [element]);
}


// Create the prototype for the behavior.
MyNameSpace.HighLightTextBox.prototype = {
    initialize: function () {
        MyNameSpace.HighLightTextBox.callBaseMethod(this, 'initialize');

        $addHandlers(this.get_element(),
            { 'focus': this._onFocus,
                'blur': this._onBlur
            },
            this);
    },

    dispose: function () {
        $clearHandlers(this.get_element());

        MyNameSpace.HighLightTextBox.callBaseMethod(this, 'dispose');
    },


    // Event delegates
    _onFocus: function (e) {
        if (this.get_element() && !this.get_element().disabled) {
            this.get_element().className = 'textBoxFocus';
        }
    },

    _onBlur: function (e) {
        if (this.get_element() && !this.get_element().disabled) {
            this.get_element().className = '';
        }
    },
}


// Register the class as a type that inherits from Sys.UI.Behaviour.
MyNameSpace.HighLightTextBox.registerClass('MyNameSpace.HighLightTextBox', Sys.UI.Behavior);

if (typeof (Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();


The Javascript is also marked as a 'Build Action' of Embedded Resource in the project properties. Building the project produces our .dll which is a fully enclosed AJAX Behaviour control, incorporating it's own Javascript and css inside the .dll, so it's now very portable, just one file.


<%@ Register Assembly="MyNameSpace" Namespace="MyNameSpace" TagPrefix="HighFlying" %>

....

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

<asp:TextBox ID="TextBox1" runat="server" /><br />

<asp:TextBox ID="TextBox2" runat="server" /><br />

<asp:TextBox ID="TextBox3" runat="server" /><br />
<HighFlying:HighLightTextBox ID="FocusExtender1" runat="server"
            TargetControlID="TextBox1" />
<HighFlying:HighLightTextBox ID="FocusExtender2" runat="server"
            TargetControlID="TextBox2" />
<HighFlying:HighLightTextBox ID="FocusExtender3" runat="server"
            TargetControlID="TextBox3" />