Condividi tramite


Aggiunta di funzionalità client a un controllo server Web

Aggiornamento: novembre 2007

La funzionalità AJAX di ASP.NET consente di espandere le funzionalità di un'applicazione Web per creare un'esperienza utente completa. È possibile utilizzare funzionalità ECMAScript (JavaScript), DHTML e AJAX del browser per includere effetti visivi, elaborazione client, ad esempio convalida e così via.

In questo argomento viene illustrato come creare un controllo server Web personalizzato che utilizza le funzionalità AJAX di ASP.NET per espandere le funzionalità del browser. È possibile aggiungere la funzionalità agli elementi del modello DOM (Document Object Model) utilizzando un controllo client. Il controllo client può essere associato a un controllo server implementando l'interfaccia IScriptControl nel controllo server.

In particolare, vengono illustrate le seguenti operazioni:

  • Creare un controllo server Web che incapsula il comportamento client e che include proprietà che gli utenti possono impostare per controllare il comportamento.

  • Creare un controllo client associato al controllo server Web.

  • Gestire eventi dal DOM del browser nel controllo client.

    Nota:

    È inoltre possibile aggiungere funzionalità client complete ai controlli server Web creando un controllo Extender. Questo controllo Extender incapsula funzionalità client in un comportamento e può essere successivamente collegato a un controllo server Web. Poiché un controllo Extender non fa parte del controllo associato, è possibile creare un solo controllo Extender che può essere associato a molti tipi di controlli server Web. Per un esempio, vedere Creazione di un controllo Extender per associare un comportamento client a un controllo server Web.

  • Compilare il controllo server Web personalizzato in un assembly e incorporare i file JavaScript associati come risorse nello stesso assembly.

  • Fare riferimento al controllo server Web personalizzato compilato in una pagina Web ASP.NET con supporto AJAX.

Identificazione dei requisiti client

Il primo passaggio per aggiungere il comportamento client a un controllo server Web consiste nel decidere quale comportamento del controllo sarà presente nel browser. È quindi possibile determinare la funzionalità client necessaria per implementare il comportamento.

Il controllo server Web creato in questo argomento implementa un comportamento client semplice. Il controllo (un controllo TextBox) viene evidenziato quando viene selezionato (o quando presenta lo stato attivo) nel browser. Ad esempio, il controllo potrebbe modificare il colore di sfondo quando presenta lo stato attivo e quindi tornare al colore predefinito quando lo stato attivo viene spostato su un altro controllo.

Per implementare questo comportamento, il controllo client in questo argomento richiede le funzionalità elencate nella tabella seguente.

  • Evidenziazione di un elemento DOM.
    Per evidenziare un elemento DOM in una pagina Web ASP.NET, il controllo client applica uno stile CSS (Cascading Style Sheet) identificato dal nome di una classe. Questo stile può essere configurato dall'utente.

  • Ripristino dello stato non evidenziato dell'elemento DOM.
    Per rimuovere l'evidenziazione da un elemento DOM in una pagina Web ASP.NET, il controllo client applica uno stile CSS identificato dal nome di una classe. Questo stile può essere configurato dall'utente e viene applicato all'elemento DOM come stile predefinito.

  • Identificazione di un elemento DOM selezionato.
    Per rilevare quando un elemento DOM è selezionato (presenta lo stato attivo), il controllo gestisce l'evento onfocus dell'elemento DOM.

  • Identificazione di un elemento DOM non selezionato.
    Per rilevare quando un controllo non è più selezionato, il controllo gestisce l'evento onblur dell'elemento DOM.

Creazione del controllo server Web

Un controllo server Web che include funzionalità client tramite la funzionalità AJAX ASP.NET è simile a qualsiasi altro controllo server Web. Tuttavia, il controllo implementa anche l’interfaccia IScriptControl dallo spazio dei nomi System.Web.UI. Il controllo in questo argomento estende il controllo TextBox ASP.NET ereditando la classe TextBox e implementando l'interfaccia IScriptControl.

Nell'esempio seguente viene illustrata la definizione della classe.

Public Class SampleTextBox
    Inherits TextBox
    Implements IScriptControl
public class SampleTextBox : TextBox, IScriptControl

Il nuovo controllo server Web include due proprietà utilizzate per implementare i requisiti client:

  • HighlightCssClass, che identifica la classe CSS che verrà applicata all'elemento DOM per evidenziare il controllo con lo stato attivo.

  • NoHighlightCssClass, che identifica la classe CSS che verrà applicata all'elemento DOM quando non presenta lo stato attivo.

Implementazione dell'interfaccia IScriptControl

Nella tabella riportata di seguito vengono elencati i membri dell’interfaccia IScriptControl che è necessario implementare in un controllo server Web.

  • GetScriptDescriptors
    Restituisce un insieme di oggetti ScriptDescriptor che contengono informazioni sulle istanze di componenti client utilizzati con il controllo server Web, ovvero il tipo client da creare, le proprietà da assegnare e gli eventi per i quali aggiungere i gestori.

  • GetScriptReferences
    Restituisce un insieme di oggetti ScriptReference che contengono informazioni sulle librerie di script client da includere con il controllo. Le librerie di script client definiscono i tipi client e il codice JavaScript necessario per il comportamento.

Il controllo server Web illustrato in questo argomento utilizza il metodo GetScriptDescriptors per definire l'istanza del tipo di controllo client. Il controllo crea un nuovo oggetto ScriptControlDescriptor (la classe ScriptControlDescriptor deriva dalla classe ScriptDescriptor) e include l'oggetto nel valore restituito per il metodo GetScriptDescriptors.

L'oggetto ScriptControlDescriptor include il nome della classe client (Samples.SampleTextBox) e il valore ClientID per il controllo server Web. Questo valore viene utilizzato come valore id per l’elemento DOM sottoposto a rendering. Il nome della classe client e i valori della proprietà ClientID vengono passati al costruttore per l'oggetto ScriptControlDescriptor.

La classe ScriptControlDescriptor viene utilizzata per impostare i valori delle proprietà del controllo ottenuti dalle proprietà del controllo server Web. Per definire le proprietà del controllo client, il controllo server Web utilizza il metodo ScriptComponentDescriptor.AddProperty della classe ScriptControlDescriptor. Il controllo server Web specifica quindi un nome e un valore per la proprietà del controllo client, in base alla proprietà corrispondente del controllo server Web. In questo esempio viene utilizzato un oggetto ScriptControlDescriptor per impostare i valori delle proprietà highlightCssClass e nohighlightCssClass nel controllo client.

Il controllo server Web fornisce l'oggetto ScriptControlDescriptor nel valore restituito per il metodo GetScriptDescriptors. Pertanto, ogni volta che viene eseguito il rendering del controllo server Web nel browser, ASP.NET consente di eseguire il rendering di JavaScript creando un'istanza del controllo client con tutte le proprietà e i gestori eventi definiti. L'istanza del controllo viene collegata all'elemento DOM, in base alla proprietà ClientID sottoposta a rendering dal controllo server Web. Nell'esempio riportato di seguito viene illustrato il codice markup ASP.NET dichiarativo che include in una pagina il controllo server Web descritto in questo argomento.

<sample:SampleTextBox 
  ID="SampleTextBox1"
  HighlightCssClass="MyHighLight"
  NoHighlightCssClass="MyLowLight" />

L'output del rendering della pagina include una chiamata al metodo $create che identifica la classe client da creare. Fornisce inoltre i valori per le proprietà client e il valore id dell'oggetto DOM a cui è associato il controllo client. Nell'esempio riportato di seguito viene illustrato un metodo $create sottoposto a rendering.

$create(Samples.SampleTextBox, {"highlightCssClass":"MyHighLight","nohighlightCssClass":"MyLowLight"}, null, null, $get('SampleTextBox1'));

Il controllo server Web di esempio, utilizza il metodo GetScriptReferences per passare il percorso della libreria di script che definisce il tipo di controllo client. In questo esempio, si tratta di un URL del file script denominato SampleTextBox.js, creato più avanti. Il riferimento viene stabilito creando un nuovo oggetto ScriptReference e impostando quindi la proprietà Path sull'URL del file che contiene il codice client.

Nell'esempio riportato di seguito vengono illustrate le implementazioni dei metodi GetScriptDescriptors e GetScriptReferences.

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();
}

Registrazione del controllo client

I controlli client devono essere registrati con l'oggetto ScriptManager per la pagina corrente. Questa operazione viene eseguita chiamando il metodo RegisterScriptControl<TScriptControl> della classe ScriptManager e fornendo un riferimento al controllo client.

Il controllo server Web di esempio, si registra automaticamente come un controllo client con il controllo ScriptManager sulla pagina. Per eseguire questa operazione, il controllo esegue l’override del metodo OnPreRender del controllo TextBox di base. Successivamente chiama il metodo RegisterScriptControl() per la registrazione come controllo client. Il controllo registra inoltre i descrittori dello script creati dal metodo GetScriptDescriptors mediante una chiamata al metodo RegisterScriptDescriptors() nel metodo Render del controllo.

Nell'esempio riportato di seguito vengono illustrate le chiamate ai metodi RegisterScriptControl() e RegisterScriptDescriptors().

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);
}

Nell'esempio riportato di seguito viene illustrato il codice completo del controllo server Web.

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();
        }
    }
}

Creazione del controllo client

Nel controllo server Web il metodo GetScriptReferences specifica un file JavaScript (SampleTextBox.js) che contiene il codice client per il tipo di controllo. In questa sezione viene descritto il codice JavaScript presente in tale file.

Il codice del controllo client corrisponde ai membri specificati negli oggetti ScriptDescriptor restituiti dal metodo GetScriptDescriptors. Un controllo client può inoltre disporre di membri che non corrispondono ai membri della classe del controllo server Web.

Il controllo server Web di esempio imposta il nome del controllo client su Samples.SampleTextBox e definisce due proprietà del controllo client, highlightCssClass e nohighlightCssClass.

Per ulteriori informazioni sulla creazione di componenti e controlli client, vedere Creazione di una classe Component del client tramite il modello di prototipo.

Registrazione dello spazio dei nomi client

Il codice del controllo client deve innanzitutto chiamare il metodo registerNamespace della classe Type per registrare il relativo spazio dei nomi (Samples). Nell'esempio riportato di seguito viene illustrato come registrare lo spazio dei nomi client.

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

Definizione della classe client

Dopo la registrazione dello spazio dei nomi client, nel codice viene definita la classe Samples.SampleTextBox. Questa classe include due proprietà contenenti i valori delle proprietà forniti dal controllo server Web. Include inoltre due delegati dell'evento che specificano i gestori per gli eventi onfocus e onblur dell'elemento DOM associato al controllo Samples.SampleTextBox.

Nell'esempio riportato di seguito viene illustrata la definizione della classe Samples.SampleTextBox.

Samples.SampleTextBox = function(element) { 
    Samples.SampleTextBox.initializeBase(this, [element]);

    this._highlightCssClass = null;
    this._nohighlightCssClass = null;
}

Definizione del prototipo della classe

Dopo avere definito la classe Samples.SampleTextBox, il codice client definisce il prototipo della classe. Il prototipo include funzioni di accesso get o set per le proprietà oltre a gestori eventi. Include inoltre un metodo initialize chiamato quando viene creata un'istanza del controllo e un metodo dispose che esegue la pulitura quando il controllo non è più richiesto dalla pagina.

Definizione dei gestori eventi per l'elemento DOM

I gestori eventi per una classe client vengono definiti come metodi del prototipo della classe. I gestori sono associati ai delegati dell'evento e agli eventi del DOM del browser utilizzando il metodo addHandlers illustrato più avanti in questo argomento insieme al metodo initialize.

Nell'esempio riportato di seguito vengono illustrati i metodi dei gestori eventi per il controllo Samples.SampleTextBox.

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

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

Definizione dei metodi Get e Set delle proprietà

Ogni proprietà identificata nell'oggetto ScriptDescriptor del metodo GetScriptDescriptors del controllo server Web deve disporre di funzioni di accesso client corrispondenti. Le funzioni di accesso delle proprietà client vengono definite come metodi get_<property name> e set_<property name> del prototipo della classe client.

Nota:

JavaScript rileva la distinzione tra maiuscole e minuscole. I nomi delle funzioni di accesso get e set devono corrispondere esattamente ai nomi delle proprietà definiti nell'oggetto ScriptDescriptor del metodo GetScriptDescriptors nel controllo server Web.

Nell'esempio riportato di seguito vengono illustrate le funzioni di accesso get e set delle proprietà per il controllo Samples.SampleTextBox.

get_highlightCssClass : function() {
    return this._highlightCssClass;
},

set_highlightCssClass : function(value) {
    if (this._highlightCssClass !== value) {
        this._highlightCssClass = value;
        this.raisePropertyChanged('highlightCssClass');
    }
},

get_nohighlightCssClass : function() {
    return this._nohighlightCssClass;
},

set_nohighlightCssClass : function(value) {
    if (this._nohighlightCssClass !== value) {
        this._nohighlightCssClass = value;
        this.raisePropertyChanged('nohighlightCssClass');
    }
}

Implementazione dei metodi Initialize e Dispose

Il metodo initialize viene chiamato quando viene creata un'istanza del controllo. Utilizzare questo metodo per impostare valori predefiniti delle proprietà, creare delegati delle funzioni e aggiungere delegati come gestori eventi.

Il metodo initialize della classe Samples.SampleTextBox esegue le seguenti operazioni:

  • Chiama il metodo initialize della classe base Sys.UI.Control.

  • Chiama il metodo addHandlers per aggiungere i delegati dell'evento come gestori per gli eventi onfocus e onblur dell'elemento HTML associato (<input type="text">). La componente "on" del nome dell'evento, ad esempio onfocus, non viene specificata.

Il metodo dispose viene chiamato quando un'istanza del controllo non viene più utilizzata nella pagina e viene rimossa. Utilizzare questo metodo per liberare le risorse che non sono più necessarie per il controllo, ad esempio i gestori eventi DOM.

Il metodo dispose della classe Sample.SampleTextBox esegue le seguenti operazioni:

  • Chiama il metodo clearHandlers per cancellare i delegati dell'evento come i gestori per gli eventi onfocus e onblur dell'elemento DOM associato.

  • Chiama il metodo dispose della classe base Control.

    Nota:

    Il metodo dispose di una classe client potrebbe essere chiamato più volte. Verificare che il codice incluso nel metodo dispose tenga conto di tale eventualità.

Nell'esempio riportato di seguito viene illustrata l'implementazione dei metodi initialize e dispose per il prototipo Samples.SampleTextBox.

initialize : function() {
    Samples.SampleTextBox.callBaseMethod(this, 'initialize');

    this._onfocusHandler = Function.createDelegate(this, this._onFocus);
    this._onblurHandler = Function.createDelegate(this, this._onBlur);

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

    this.get_element().className = this._nohighlightCssClass;
},

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

    Samples.SampleTextBox.callBaseMethod(this, 'dispose');
},

Registrazione del controllo

L'ultima attività per la creazione del controllo client consiste nella registrazione della classe client tramite la chiamata al metodo registerClass. Poiché la classe è un controllo client, la chiamata al metodo registerClass include il nome della classe JavaScript da registrare. Specifica inoltre Control come classe base.

Nell'esempio riportato di seguito viene illustrata la chiamata al metodo registerClass per il controllo Samples.SampleTextBox. Nell'esempio viene inoltre inclusa una chiamata al metodo notifyScriptLoaded dell'oggetto Sys.Application. Questa chiamata è necessaria per notificare a Microsoft AJAX Library il caricamento del file JavaScript.

Samples.SampleTextBox.registerClass('Samples.SampleTextBox', Sys.UI.Control);

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

Nell'esempio riportato di seguito viene illustrato il codice completo per il controllo client Samples.SampleTextBox.

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

//
// Define the control properties.
//
Samples.SampleTextBox = function(element) { 
    Samples.SampleTextBox.initializeBase(this, [element]);

    this._highlightCssClass = null;
    this._nohighlightCssClass = null;
}

//
// Create the prototype for the control.
//

Samples.SampleTextBox.prototype = {


    initialize : function() {
        Samples.SampleTextBox.callBaseMethod(this, 'initialize');

        this._onfocusHandler = Function.createDelegate(this, this._onFocus);
        this._onblurHandler = Function.createDelegate(this, this._onBlur);

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

        this.get_element().className = this._nohighlightCssClass;
    },

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

        Samples.SampleTextBox.callBaseMethod(this, 'dispose');
    },

    //
    // Event delegates
    //

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

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


    //
    // Control properties
    //

    get_highlightCssClass : function() {
        return this._highlightCssClass;
    },

    set_highlightCssClass : function(value) {
        if (this._highlightCssClass !== value) {
            this._highlightCssClass = value;
            this.raisePropertyChanged('highlightCssClass');
        }
    },

    get_nohighlightCssClass : function() {
        return this._nohighlightCssClass;
    },

    set_nohighlightCssClass : function(value) {
        if (this._nohighlightCssClass !== value) {
            this._nohighlightCssClass = value;
            this.raisePropertyChanged('nohighlightCssClass');
        }
    }
}

// Optional descriptor for JSON serialization.
Samples.SampleTextBox.descriptor = {
    properties: [   {name: 'highlightCssClass', type: String},
                    {name: 'nohighlightCssClass', type: String} ]
}

// Register the class as a type that inherits from Sys.UI.Control.
Samples.SampleTextBox.registerClass('Samples.SampleTextBox', Sys.UI.Control);

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

Compilazione dinamica del controllo per il test

Prima di poter fare riferimento a un controllo server Web, ad esempio al controllo illustrato in questo argomento, in una pagina Web, è necessario compilarlo. È possibile utilizzare la funzionalità di compilazione dinamica di ASP.NET versione 2.0 per testare i controlli server Web senza doverli compilare manualmente in un assembly. In questo modo si risparmia tempo durante la scrittura e il debug iniziali del codice del controllo server Web. Nei passaggi seguenti viene illustrato come utilizzare la cartella App_Code per compilare in modo dinamico il controllo.

Per inserire il controllo nella cartella App_Code per la compilazione dinamica

  1. Creare una cartella App_Code nella cartella radice del sito Web.

  2. Spostare i file di origine del controllo, con estensione .cs o .vb, e tutte le classi correlate nella cartella App_Code

    -oppure-

    Se è già stato aggiunto un assembly per il controllo nella cartella Bin, eliminare l'assembly. Continuare a modificare i file di origine nella cartella App_Code. Il codice sorgente del controllo verrà compilato ogni volta che si esegue il progetto.

    Nota:

    È possibile precompilare un controllo in un assembly e salvare l'assembly nella cartella Bin oppure salvare il file di origine del controllo nella cartella App_Code, ma non è possibile effettuare entrambe le operazioni. Se si aggiunge il controllo in entrambe le cartelle, il parser della pagina non sarà in grado di risolvere un riferimento al controllo in una pagina e genererà un errore.

  3. Eseguire la pagina Web.

    Il controllo viene compilato dinamicamente.

Test del controllo compilato dinamicamente in una pagina Web

Nella procedura descritta di seguito viene illustrato come verificare il controllo in una pagina Web ASP.NET con supporto AJAX. Il codice per il controllo server Web viene compilato in modo dinamico dalla cartella App_Code.

Per utilizzare il comportamento in una pagina ASP.NET

  1. Creare una nuova pagina Web ASP.NET.

  2. Se nella pagina non è già presente un controllo ScriptManager, aggiungerne uno.

  3. Creare le regole di stile CSS per le caselle di testo evidenziate e per le caselle di testo non evidenziate.

    È possibile evidenziare il controllo in qualsiasi modo. Ad esempio, è possibile modificare il colore di sfondo del controllo, aggiungere un bordo o modificare il tipo di carattere del testo.

  4. Aggiungere una direttiva @ Register alla pagina, quindi specificare lo spazio dei nomi e l'attributo TagPrefix per il controllo, come illustrato nell'esempio riportato di seguito.

    Nota:

    In questo caso, il codice del controllo server si trova nella cartella App_Code in modo da poter essere compilato in modo dinamico. Pertanto, non viene specificato un attributo dell'assembly.

  5. Aggiungere un controllo TextBox e un controllo Button alla pagina e impostare le relative proprietà ID.

    Il markup dei controlli deve includere .

  6. Aggiungere un'istanza del controllo FocusExtender alla pagina.

  7. Impostare la proprietà TargetControlID del controllo FocusExtender sull'ID del controllo Button aggiunto in precedenza.

  8. Impostare la proprietà HighlightCssClass sullo stile CSS di evidenziazione e impostare la proprietà NoHighlightCssClass sullo stile CSS di non evidenziazione.

  9. Eseguire la pagina e selezionare ciascun controllo.

    Quando viene selezionato, il controllo Button è evidenziato.

Nell'esempio riportato di seguito viene illustrata una pagina ASP.NET che utilizza il comportamento creato in questo argomento.

Compilazione del controllo in un assembly

Incorporando il componente JavaScript e il codice di estensione del controllo server Web in un assembly, sarà più semplice distribuire il controllo personalizzato. La creazione di un assembly semplifica inoltre la gestione del controllo delle versioni per il controllo. Inoltre, non è possibile aggiungere i controlli alla casella degli strumenti di una finestra di progettazione se non sono stati compilati in un assembly.

Nella procedura descritta di seguito viene illustrato come creare una nuova libreria di codice nel progetto esistente relativo all'argomento, utilizzando Visual Studio. Una copia dei file di codice verrà spostata in una nuova libreria di codice nel progetto di questo argomento. La compilazione del controllo in una libreria di codice creerà un assembly che può essere distribuito.

Nota:

Per eseguire questa procedura, è necessario utilizzare Microsoft Visual Studio 2005. Non è possibile utilizzare Visual Web Developer 2005 Express Edition, perché Visual Web Developer Express Edition non consente la creazione di due progetti nella stessa soluzione.

Per aggiungere una nuova libreria di codice al progetto esistente

  1. In Visual Studio scegliere Nuovo dal menu File, quindi Progetto.

    Verrà visualizzata la finestra di dialogo Nuovo progetto.

  2. In Tipi progetto selezionare Visual C# o Visual Basic.

  3. In Modelli selezionare Libreria di classi e denominare il progetto Samples.

  4. Nell'elenco Soluzione selezionare Aggiungi a soluzione, quindi fare clic su OK.

    La libreria di classi Samples viene aggiunta alla soluzione esistente.

Per spostare il controllo server personalizzato in una libreria di codice

  1. Aggiungere al progetto della libreria di classi Samples i seguenti riferimenti, richiesti dal controllo server personalizzato:

    • System.Drawing

    • System.Web

    • System.Web.Extensions

  2. In Esplora soluzioni copiare il file SampleTextBox.cs o SampleTextBox.vb e il file SampleTextBox.js dal progetto originale, quindi aggiungere i file copiati nella radice del progetto della libreria di classi Samples.

  3. Nella finestra Proprietà del file SampleTextBox.js impostare Operazione di compilazione su Risorsa incorporata.

  4. Aggiungere al file AssemblyInfo la seguente proprietà.

    <Assembly: WebResource("Samples.SampleTextBox.js", "text/javascript")>
    
    [assembly: System.Web.UI.WebResource("Samples.SampleTextBox.js", "text/javascript")]
    
    Nota:

    Il file AssemblyInfo.vb si trova nel nodo Progetto di Esplora soluzioni. Se non sono presenti file nel nodo Progetto, scegliere Mostra tutti i file dal menu Progetto. Il file AssemblyInfo.cs si trova nel nodo Proprietà di Esplora soluzioni.

    La definizione WebResource per i file JavaScript deve seguire una convenzione di denominazione corrispondente a [spazio dei nomi dell'assembly].[Nome file JavaScript].js.

    Nota:

    Per impostazione predefinita, in Visual Studio lo spazio dei nomi dell'assembly viene impostato sul nome dell'assembly. È possibile modificare lo spazio dei nomi dell'assembly nelle proprietà dell'assembly.

  5. Nel file della classe SampleTextBox modificare l'oggetto ScriptReference nel metodo GetScriptReferences per fare riferimento allo script del controllo client incorporato nell'assembly "Samples". A tale scopo, apportare le seguenti modifiche:

    • Sostituire la proprietà Path con una proprietà Assembly impostata su "Samples".

    • Aggiungere una proprietà Name e impostarne il valore su "Samples.SampleTextBox.js".

    Nell'esempio riportato di seguito viene illustrato il risultato di questa modifica.

            Protected Overridable Function GetScriptReferences() As IEnumerable(Of ScriptReference)
                Dim reference As ScriptReference = New ScriptReference()
                reference.Assembly = "Samples"
                reference.Name = "Samples.SampleTextBox.js"
    
                Return New ScriptReference() {reference}
            End Function
    
            protected virtual IEnumerable<ScriptReference> GetScriptReferences()
            {
                ScriptReference reference = new ScriptReference();
                reference.Assembly = "Samples";
                reference.Name = "Samples.SampleTextBox.js";
    
                return new ScriptReference[] { reference };
            }
    
  6. Compilare il progetto.

    Al termine della compilazione, si otterrà un assembly denominato Sample.dll. Il file di codice JavaScript (SampleTextBox.js) viene incorporato in questo assembly come risorsa.

    Nota:

    Ricordare di ricompilare il progetto libreria di classi ogni volta che vengono aggiunti nuovi file di origine o vengono modificati quelli esistenti.

Utilizzo del controllo compilato dal relativo assembly in una pagina Web

Verrà ora fatto riferimento al controllo personalizzato compilato in una pagina Web ASP.NET con supporto AJAX.

Per fare riferimento al controllo personalizzato in una pagina Web ASP.NET con supporto AJAX

  1. Creare un nuovo progetto ASP.NET AJAX.

  2. Nella directory radice del sito Web, creare una cartella Bin.

  3. Copiare l'assembly Samples.dll dalla cartella Bin\Debug o Bin\Release del progetto libreria di classi Samples nella nuova cartella Bin.

  4. Aggiungere una nuova pagina Web ASP.NET denominata TestSampleTextBoxAssembly.aspx, quindi aggiungere il markup seguente alla nuova pagina.

    <%@ Register Assembly="Samples" Namespace="Samples.VB" TagPrefix="sample" %>
    
    <%@ Register Assembly="Samples" Namespace="Samples.CS" TagPrefix="sample" %>
    

    Poiché il controllo server viene compilato in un assembly, la direttiva @ Register presenta un attributo Assembly che fa riferimento all'assembly "Samples" oltre agli attributi Namespace e TagPrefix.

  5. Eseguire la pagina e selezionare ciascun controllo.

    Quando viene selezionato, il controllo SampleTextBox viene evidenziato.

La pagina Web che utilizza il controllo personalizzato compilato include l'attributo Assembly nella direttiva @ Register. In caso contrario, corrisponde alla pagina Web utilizzata per il controllo nella cartella App_Code.

Vedere anche

Concetti

Creazione di un controllo Extender per associare un comportamento client a un controllo server Web

Utilizzo del controllo UpdatePanel ASP.NET con più controlli con associazione a dati

Riferimenti

Classe Sys.UI.Control

IScriptControl

ScriptManager