Crear un extensor de control personalizado de AJAX Control Toolkit (C#)

de Microsoft

Los extensores personalizados permiten personalizar y ampliar las funcionalidades de los controles de ASP.NET sin tener que crear nuevas clases.

En este tutorial, aprenderá a crear un extensor de control personalizado para el kit de herramientas de control de AJAX. Vamos a crear un extensor sencillo pero útil, que cambia el estado de un botón de deshabilitado a habilitado al escribir texto en un TextBox. Después de leer este tutorial, podrá ampliar el kit de herramientas de AJAX de ASP.NET con sus propios extensores de control.

Puede crear extensores de control personalizados mediante Visual Studio o Visual Web Developer (asegúrese de disponer de la versión más reciente de Visual Web Developer).

Información general sobre el extensor DisabledButton

Nuestro nuevo extensor de control se denomina DisabledButton. Este extensor tendrá tres propiedades:

  • TargetControlID: el TextBox que el control extiende;
  • TargetButtonIID: el botón que está deshabilitado o habilitado;
  • DisabledText: el texto que se muestra inicialmente en el botón. Al empezar a escribir, el botón muestra el valor de la propiedad de texto del botón.

El extensor DisabledButton se enlaza con un control de botón y de TextBox. Antes de escribir cualquier texto, el botón está deshabilitado, y el TextBox y el botón presentan el siguiente aspecto:

Image of disabled button

(Haga clic para ver la imagen a tamaño completo.)

Después de empezar a escribir texto, el botón se habilita; el TextBox y el botón presentan el siguiente aspecto:

Image of enabled button

(Haga clic para ver la imagen a tamaño completo.)

Para crear el extensor de control, es preciso crear los tres archivos siguientes:

  • DisabledButtonExtender.cs: este archivo es la clase de control del lado servidor que administra la creación del extensor y permite configurar las propiedades en tiempo de diseño. También define las propiedades que se pueden establecer en el extensor. Estas propiedades son accesibles a través del código y en tiempo de diseño, y coinciden con las definidas en el archivo DisableButtonBehavior.js;
  • DisabledButtonBehavior.js: este archivo es donde se agrega toda la lógica de script de cliente;
  • DisabledButtonDesigner.cs: esta clase habilita la funcionalidad en tiempo de diseño. Necesita esta clase si desea que el extensor de control funcione correctamente con el diseñador de Visual Studio/Visual Web Developer.

Por lo tanto, un extensor de control consta de un control del lado servidor, un comportamiento del lado cliente y una clase de diseñador del lado servidor. En las secciones siguientes, aprenderá a crear estos tres archivos.

Creación del sitio web y el proyecto del extensor personalizado

El primer paso consiste en crear un sitio web y un proyecto de biblioteca de clases en Visual Studio/Visual Web Developer. Crearemos el extensor personalizado en el proyecto de biblioteca de clases y lo pondremos a prueba en el sitio web.

Comencemos con el sitio web. Siga los siguientes pasos para crear el sitio web:

  1. Seleccione la opción de menú Archivo, Nuevo sitio web.
  2. Seleccione la plantilla Sitio web ASP.NET.
  3. Nombre el nuevo sitio web como Website1.
  4. Haga clic en el botón Aceptar .

A continuación, tenemos que crear el proyecto de biblioteca de clases que contendrá el código para el extensor de control:

  1. Seleccione la opción de menú Archivo, Nuevo proyecto.
  2. Haga clic en la plantilla Biblioteca de clases.
  3. Asigne a la nueva biblioteca de clases el nombre CustomExtenders.
  4. Haga clic en el botón Aceptar .

Una vez completados estos pasos, la ventana del Explorador de soluciones debe presentar una apariencia similar a la de la figura 1.

Solution with website and class library project

Figura 01: Solución con sitio web y proyecto de biblioteca de clases (haga clic para ver la imagen en tamaño completo)

A continuación, debe agregar todas las referencias de ensamblado necesarias al proyecto de biblioteca de clases:

  1. Haga clic con el botón derecho en el proyecto CustomExtenders y seleccione la opción de menú Agregar referencia.

  2. Seleccione la pestaña .NET.

  3. Agregue referencias a los siguientes ensamblados:

    1. System.Web.dll
    2. System.Web.Extensions.dll
    3. System.Design.dll
    4. System.Web.Extensions.Design.dll
  4. Seleccione la pestaña Examinar.

  5. Agregue una referencia al ensamblado AjaxControlToolkit.dll. Este ensamblado se encuentra en la carpeta donde se descargó el kit de herramientas de control de AJAX.

Una vez finalizados estos pasos, la carpeta de referencias del proyecto de biblioteca de clases debe presentar una apariencia similar a la de la figura 2.

References folder with required references

Figura 02: Carpeta de referencias con las referencias necesarias (haga clic para ver la imagen en tamaño completo)

Creación de un extensor de control personalizado

Ahora que tenemos nuestra biblioteca de clases, podemos empezar a crear nuestro control extensor. Comencemos con la estructura básica de una clase de control extensor personalizada (véase la lista 1).

Lista 1 - MyCustomExtender.cs

using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;
using AjaxControlToolkit;

[assembly: System.Web.UI.WebResource("CustomExtenders.MyControlBehavior.js", "text/javascript")]

namespace CustomExtenders
{
    [ClientScriptResource("CustomExtenders.MyControlBehavior", "CustomExtenders.MyControlBehavior.js")]
    [TargetControlType(typeof(TextBox))]
    public class MyControlExtender : ExtenderControlBase
    {

        [ExtenderControlProperty]
        [DefaultValue("")]
        public string MyProperty
        {
            get
            {
                return GetPropertyValue("MyProperty", "");
            }
            set
            {
                SetPropertyValue("MyProperty", value);
            }
        }
    }
}

Podemos observar varias cosas sobre la clase del extensor de control en la lista 1. En primer lugar, observe que la clase hereda sus características de la clase base ExtenderControlBase. Todos los controles extensores del kit de herramientas de control de AJAX derivan de esta clase base. Por ejemplo, la clase base incluye la propiedad TargetID, que es una propiedad necesaria de cada extensor de control.

Observe también que la clase incluye los dos atributos siguientes en relación con el script de cliente:

  • WebResource: hace que un archivo se incluya como un recurso incrustado en un ensamblado;
  • ClientScriptResource: hace que se recupere un recurso de script de un ensamblado.

Se utiliza el atributo WebResource para insertar el archivo de JavaScript MyControlBehavior.js en el ensamblado cuando se compila el extensor personalizado. Se utiliza el atributo ClientScriptResource para recuperar el script MyControlBehavior.js del ensamblado cuando se utiliza el extensor personalizado en un sitio web.

Para que funcionen los atributos WebResource y ClientScriptResource, debe compilar el archivo JavaScript como un recurso incrustado. Seleccione el archivo en la ventana del Explorador de soluciones, abra la hoja de propiedades y asigne el valor Recurso incrustada propiedad Acción de compilación.

Observe que el extensor de control también incluye un atributo TargetControlType. Este atributo se usa para especificar el tipo de control que extiende el extensor de control. En el caso de la lista 1, el extensor de control se usa para extender un TextBox.

Por último, observe que el extensor personalizado incluye una propiedad denominada MyProperty. La propiedad está marcada con el atributo ExtenderControlProperty. Se utilizan los métodos GetPropertyValue() y SetPropertyValue() para transferir el valor de la propiedad del extensor de control del lado servidor al comportamiento del lado cliente

Sigamos con la ejecución del código para el extensor DisabledButton. El código de este extensor figura en la lista 2.

Lista 2 - DisabledButtonExtender.cs

using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;
using AjaxControlToolkit;

[assembly: System.Web.UI.WebResource("CustomExtenders.DisabledButtonBehavior.js", "text/javascript")]

namespace CustomExtenders
{
    [ClientScriptResource("CustomExtenders.DisabledButtonBehavior", "CustomExtenders.DisabledButtonBehavior.js")]
    [TargetControlType(typeof(TextBox))]
    public class DisabledButtonExtender : ExtenderControlBase
    {
        [ExtenderControlProperty]
        [DefaultValue("")]
        [IDReferenceProperty(typeof(Button))]
        public string TargetButtonID
        {
            get
            {
                return GetPropertyValue("TargetButtonID", "");
            }
            set
            {
                SetPropertyValue("TargetButtonID", value);
            }
        }

        [ExtenderControlProperty]
        [DefaultValue("")]
        public string DisabledText
        {
            get
            {
                return GetPropertyValue("DisabledText", "");
            }
            set
            {
                SetPropertyValue("DisabledText", value);
            }
        }

    }
}

El extensor DisabledButton de la lista 2 tiene dos propiedades, denominadas TargetButtonID y DisabledText. La propiedad IDReferenceProperty aplicada a la propiedad TargetButtonID impide asignar a esta propiedad todo lo que no sea un identificador de control de botón.

Los atributos WebResource y ClientScriptResource asocian con este extensor un comportamiento del lado cliente ubicado en un archivo denominado DisabledButtonBehavior.js. En la sección siguiente, se describe este archivo de JavaScript.

Creación del comportamiento del extensor personalizado

El componente del lado cliente de un extensor de control se denomina «comportamiento». La lógica real para deshabilitar y habilitar el botón se encuentra en el comportamiento DisabledButton. El código de JavaScript para el comportamiento se incluye en la lista 3.

Lista 3 - DisabledButton.js

Type.registerNamespace('CustomExtenders');

CustomExtenders.DisabledButtonBehavior = function(element) {

    CustomExtenders.DisabledButtonBehavior.initializeBase(this, [element]);

    this._targetButtonIDValue = null;
    this._disabledTextValue = null;

}

CustomExtenders.DisabledButtonBehavior.prototype = {

    initialize : function() {
        CustomExtenders.DisabledButtonBehavior.callBaseMethod(this, 'initialize');

        // Initalization code
        $addHandler(this.get_element(), 'keyup', 
        Function.createDelegate(this, this._onkeyup));
        this._onkeyup();
    },

    dispose : function() {
        // Cleanup code 

        CustomExtenders.DisabledButtonBehavior.callBaseMethod(this, 'dispose');
    },

    // Property accessors 
    //
    get_TargetButtonID : function() {
        return this._targetButtonIDValue;
    },

    set_TargetButtonID : function(value) {
        this._targetButtonIDValue = value;
    },

    get_DisabledText : function() {
        return this._disabledTextValue;
    },

    set_DisabledText : function(value) {
        this._disabledTextValue = value;
    },

  _onkeyup : function() {
  
    var e = $get(this._targetButtonIDValue);
    if (e) {
      var disabled = ("" == this.get_element().value);
      e.disabled = disabled;
      if ( this._disabledTextValue) {
        if (disabled) {
          this._oldValue = e.value;
          e.value = this._disabledTextValue;
        }
        else
        {
          if(this._oldValue){
            e.value = this._oldValue;
          }
        }
      }
    }
  }

}

CustomExtenders.DisabledButtonBehavior.registerClass('CustomExtenders.DisabledButtonBehavior', AjaxControlToolkit.BehaviorBase);

El archivo JavaScript de la lista 3 contiene una clase de lado cliente denominada DisabledButtonBehavior. Esta clase, al igual que su gemela en el lado servidor, incluye dos propiedades denominadas TargetButtonID y DisabledText a las que se puede acceder mediante get_TargetButtonID/set_TargetButtonID y get_DisabledText/set_DisabledText.

El método initialize() asocia un controlador de eventos de KeyUp al elemento de destino para el comportamiento. Cada vez que escriba una letra en el TextBox asociado a este comportamiento, se ejecuta el controlador de KeyUp. El controlador de KeyUp habilita o deshabilita el botón en función de si el control de TextBox asociado al comportamiento contiene texto.

Recuerde que debe compilar el archivo JavaScript de la lista 3 como recurso incrustado. Seleccione el archivo en la ventana del Explorador de soluciones, abra la hoja de propiedades y asigne el valor Recurso incrustada propiedad Acción de compilación (véase la figura 3). Esta opción está disponible tanto en Visual Studio como en Visual Web Developer.

Adding a JavaScript file as an embedded resource

Figura 03: Agregar un archivo de JavaScript como recurso incrustado (haga clic para ver la imagen en tamaño completo)

Creación del diseñador del extensor personalizado

Hay una última clase que necesitamos crear para completar el extensor: es preciso crear la clase de diseñador de la lista 4. Esta clase es necesaria para que el extensor se comporte correctamente con el diseñador de Visual Studio/Visual Web Developer.

Lista 4 - DisabledButtonDesigner.cs

using System.Web.UI.WebControls;
using System.Web.UI;

namespace CustomExtenders
{
    class DisabledButtonDesigner : AjaxControlToolkit.Design.ExtenderControlBaseDesigner
    {
    }
}

El diseñador se asocia en la lista 4 al extensor DisabledButton con el atributo de diseñador. Este atributo se aplica a la clase DisabledButtonExtender de la siguiente manera:

[Designer(typeof(DisabledButtonDesigner))]
[ClientScriptResource("CustomExtenders.DisabledButtonBehavior", "CustomExtenders.DisabledButtonBehavior.js")]
[TargetControlType(typeof(TextBox))]
public class DisabledButtonExtender : ExtenderControlBase
{

Uso del extensor personalizado

Ahora que hemos terminado de crear el extensor de control DisabledButton, es el momento de utilizarlo en nuestro sitio web de ASP.NET. En primer lugar, es necesario agregar el extensor personalizado al cuadro de herramientas. Siga estos pasos:

  1. Abra una página de ASP.NET; para ello, haga doble clic en la página de la ventana del Explorador de soluciones.
  2. Haga clic con el botón derecho en el cuadro de herramientas y seleccione Elegir elementos.
  3. En el cuadro de diálogo «Elegir elementos del cuadro de herramientas», acceda al ensamblado CustomExtenders.dll.
  4. Haga clic en el botón Aceptar para cerrar el cuadro de diálogo.

Una vez completados estos pasos, el extensor de control DisabledButton debería aparecer en el cuadro de herramientas (véase la figura 4).

DisabledButton in the toolbox

Figura 04: DisabledButton en el cuadro de herramientas (haga clic para ver la imagen en tamaño completo)

A continuación, es preciso crear una nueva página de ASP.NET. Siga estos pasos:

  1. Cree una página de ASP.NET denominada ShowDisabledButton.aspx.
  2. Arrastre un ScriptManager a la página.
  3. Arrastre un control de TextBox a la página.
  4. Arrastre un control de botón a la página.
  5. En el ventana de propiedades, cambie la propiedad de ID del botón al valor btnSave y la propiedad de texto al valor Save*.

Hemos creado una página de ASP.NET con un control estándar de botón y de TextBox.

A continuación, es necesario extender el control TextBox con el extensor DisabledButton:

  1. Seleccione la opción de tarea Agregar extensor para abrir el cuadro de diálogo con el asistente del extensor (véase la figura 5). Observe que el cuadro de diálogo incluye nuestro extensor DisabledButton personalizado.
  2. Seleccione el extensor DisabledButton y haga clic en el botón Aceptar.

The Extender Wizard dialog

Figura 05: Cuadro de diálogo del asistente del extensor (haga clic para ver la imagen en tamaño completo)

Por último, podemos establecer las propiedades del extensor DisabledButton. Modifique las propiedades del control de TextBox para cambiar las propiedades del extensor DisabledButton:

  1. Seleccione el control de TextBox en el diseñador.
  2. En el ventana Propiedades, expanda el nodo de extensores (véase la figura 6).
  3. Asigne el valor Save a la propiedad DisabledText y el valor btnSave a la propiedad TargetButtonID.

Setting extender properties

Figura 06: Configuración de propiedades del extensor (haga clic para ver la imagen en tamaño completo)

Al ejecutar la página (pulsando F5), el control de botón está inicialmente deshabilitado. El control de botón se habilita en cuanto se empieza a escribir texto en el TextBox (véase la figura 7).

The DisabledButton extender in action

Figura 07: El extensor DisabledButton en acción (haga clic para ver la imagen en tamaño completo)

Resumen

El objetivo de este tutorial era explicar cómo se puede ampliar el kit de herramientas de control de AJAX con controles extensores personalizados. En este tutorial, hemos creado un extensor de control simple DisabledButton. Hemos ejecutado este extensor mediante la creación de una clase DisabledButtonExtender, un comportamiento DisabledButtonBehavior de JavaScript y una clase DisabledButtonDesigner. Siga un conjunto de pasos similar cada vez que quiera crear un extensor de control personalizado.