次の方法で共有


Web サーバー コントロールへのクライアント機能の追加

更新 : 2007 年 11 月

ASP.NET の AJAX 機能を利用すると、Web アプリケーションの機能を拡張して充実したユーザー エクスペリエンスを作成できます。Web ブラウザの ECMAScript (JavaScript)、DHTML、および AJAX の各機能により、視覚効果や、検証などのクライアント処理を追加できます。

このトピックでは、ASP.NET の AJAX 機能を使用してブラウザの機能を拡張するカスタム Web サーバー コントロールの作成方法について説明します。クライアント コントロールを使用して、クライアントのドキュメント オブジェクト モデル (DOM: Document Object Model) 要素に機能を追加できます。クライアント コントロールは、サーバー コントロールの IScriptControl インターフェイスを実装することにより、そのサーバー コントロールに関連付けることができます。

このトピックでは、次の作業を行う方法について説明します。

  • クライアント動作をカプセル化し、動作を制御するためにユーザーが設定できるプロパティを含む Web サーバー コントロールを作成します。

  • Web サーバー コントロールに関連付けられるクライアント コントロールを作成します。

  • クライアント コントロールのブラウザ DOM からイベントを処理します。

    Bb386450.alert_note(ja-jp,VS.90).gifメモ :

    エクステンダ コントロールを作成すると、Web サーバー コントロールに充実したクライアント機能を追加できます。このエクステンダ コントロールは、動作のクライアント機能をカプセル化した後、Web サーバー コントロールに結合できます。エクステンダ コントロールは、関連付けられているコントロールの一部ではないため、さまざまな種類の Web サーバー コントロールに関連付けることができる 1 つのエクステンダ コントロールを作成できます。例については、「クライアント動作と Web サーバー コントロールとを関連付けるエクステンダ コントロールの作成」を参照してください。

  • カスタム Web サーバー コントロールをコンパイルしてアセンブリを生成し、関連付けられた JavaScript ファイルを同じアセンブリにリソースとして埋め込みます。

  • ASP.NET AJAX 対応の Web ページで、コンパイル済みのカスタム Web サーバー コントロールを参照します。

クライアント要件の識別

クライアント動作を Web サーバー コントロールに追加するには、まずブラウザにおけるコントロールの動作を決定します。次に、動作の実装に必要なクライアント機能を判別します。

このトピックで作成する Web サーバー コントロールは、単純なクライアント動作を実装します。コントロール (TextBox コントロール) がブラウザで選択される (フォーカスを得る) と、強調表示されます。たとえば、コントロールがフォーカスを得たときに背景色を変更し、フォーカスが別のコントロールに移動したときに既定の色に戻すことができます。

この動作を実装するには、このトピックのクライアント コントロールが次の表に示す機能を備えている必要があります。

  • DOM 要素を強調表示する方法
    ASP.NET Web ページ内の DOM 要素を強調表示するために、クライアント コントロールは、クラス名により識別されるカスケード スタイル シート (CSS: Cascading Style Sheet) スタイルを適用します。このスタイルはユーザーが構成できます。

  • DOM 要素を強調表示されていない状態に戻す方法
    ASP.NET Web ページ内の DOM 要素から強調表示を削除するために、クライアント コントロールは、クラス名により識別される CSS スタイルを適用します。このスタイルはユーザーが構成でき、既定のスタイルとして DOM 要素に適用されます。

  • DOM 要素がいつ選択されたかを識別する方法
    DOM 要素がいつ選択されたか (フォーカスを得たか) を識別するために、コントロールは DOM 要素の onfocus イベントを処理します。

  • DOM 要素がいつ選択解除されたかを識別する方法
    コントロールがいつ選択解除されたかを識別するために、コントロールは DOM 要素の onblur イベントを処理します。

Web サーバー コントロールの作成

ASP.NET AJAX 機能を使用してクライアント機能を実現する Web サーバー コントロールは、他の Web サーバー コントロールに似ています。ただし、このコントロールには IScriptControl インターフェイスを System.Web.UI 名前空間から実装することもできます。このトピックでは、TextBox クラスを継承し、IScriptControl インターフェイスを実装して、ASP.NET TextBox コントロールを拡張します。

クラス定義の例を次に示します。

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

新しい Web サーバー コントロールには、クライアント要件の実装に使用される 2 つのプロパティがあります。

  • HighlightCssClass は、DOM 要素に適用される CSS クラスを識別し、コントロールがフォーカスを得たときに強調表示します。

  • NoHighlightCssClass は、フォーカスがないときに DOM 要素に適用される CSS クラスを識別します。

IScriptControl インターフェイスの実装

Web サーバー コントロールで実装する必要がある IScriptControl インターフェイスのメンバを次の表に示します。

  • GetScriptDescriptors
    Web サーバー コントロールと共に使用されるクライアント コンポーネントのインスタンスに関する情報を含む ScriptDescriptor オブジェクトのコレクションを返します。これには、作成するクライアントの種類、割り当てるプロパティ、およびハンドラが追加されるイベントが含まれます。

  • GetScriptReferences
    コントロールに含めるクライアント スクリプト ライブラリに関する情報を含む ScriptReference オブジェクトのコレクションを返します。クライアント スクリプト ライブラリは、クライアントの種類、および動作に必要なその他の JavaScript コードを定義します。

このトピックの Web サーバー コントロールは、GetScriptDescriptors メソッドを使用してクライアント コントロール型のインスタンスを定義します。コントロールは新しい ScriptControlDescriptor オブジェクト (ScriptControlDescriptor クラスは ScriptDescriptor クラスから派生します) を作成し、そのオブジェクトを GetScriptDescriptors メソッドの戻り値に格納します。

ScriptControlDescriptor オブジェクトは、クライアント クラス (Samples.SampleTextBox) の名前、および Web サーバー コントロールの ClientID 値を格納します。この値は、描画される DOM 要素の id 値に使われます。クライアント クラス名と ClientID プロパティ値は、ScriptControlDescriptor オブジェクトのコンストラクタに渡されます。

ScriptControlDescriptor クラスは、クライアント コントロールのプロパティ値の設定に使用されます。このプロパティ値は、Web サーバー コントロールのプロパティから取得されます。クライアント コントロールのプロパティを定義するために、Web サーバー コントロールは ScriptControlDescriptor クラスの ScriptComponentDescriptor.AddProperty メソッドを使用します。次に、Web サーバー コントロールは、Web サーバー コントロールの対応するプロパティに基づいて、クライアント コントロールのプロパティの名前と値を指定します。この例では ScriptControlDescriptor オブジェクトを使用して、クライアント コントロールの highlightCssClass プロパティと nohighlightCssClass プロパティの値を設定します。

Web サーバー コントロールは、GetScriptDescriptors メソッドの戻り値で ScriptControlDescriptor オブジェクトを渡します。したがって、Web サーバー コントロールがブラウザに表示されると、ASP.NET は定義済みのすべてのプロパティとイベント ハンドラを使用して、クライアント コントロールのインスタンスを作成する JavaScript を表示します。コントロール インスタンスは、Web サーバー コントロールから表示される ClientID プロパティに基づいて DOM 要素に追加されます。このトピックの Web サーバー コントロールをページ内に追加する ASP.NET 宣言マークアップの例を次に示します。

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

ページのレンダリングされた出力には、作成するクライアント クラスを識別する $create メソッドの呼び出しが含まれます。また、クライアントのプロパティの値、およびクライアント コントロールと関連付けられている DOM オブジェクトの id 値が提供されます。レンダリングされた $create メソッドの例を次に示します。

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

この例の Web サーバー コントロールは、GetScriptReferences メソッドを使用して、クライアント コントロール型を定義するスクリプト ライブラリの場所を渡します。この例では、後で作成する SampleTextBox.js という名前のスクリプト ファイルへの URL が該当します。新しい ScriptReference オブジェクトを作成した後、Path プロパティをクライアント コードを含むファイルの URL に設定することで、参照が行われます。

GetScriptDescriptors メソッドおよび 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();
}

クライアント コントロールの登録

クライアント コントロールは、現在のページの ScriptManager オブジェクトに登録する必要があります。これは、ScriptManager クラスの RegisterScriptControl<TScriptControl> メソッドを呼び出して、クライアント コントロールに参照を渡すことによって行われます。

この例の Web サーバー コントロールは、自身をクライアント コントロールとしてページの ScriptManager コントロールに登録します。これを行うために、このコントロールは基本 TextBox コントロールの OnPreRender メソッドをオーバーライドします。次に、RegisterScriptControl() メソッドを呼び出し、クライアント コントロールとして自身を登録します。また、GetScriptDescriptors メソッドによって作成されたスクリプト記述子を登録します。これは、コントロールの Render メソッド内で RegisterScriptDescriptors() メソッドを呼び出すことで行われます。

RegisterScriptControl() メソッドおよび 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);
}

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

クライアント コントロールの作成

Web サーバー コントロールでは、GetScriptReferences メソッドは、コントロール型のクライアント コードを含む JavaScript ファイル (SampleTextBox.js) を指定します。ここでは、そのファイル内の JavaScript コードについて説明します。

クライアント コントロール コードは、GetScriptDescriptors メソッドが返す ScriptDescriptor オブジェクトに指定されたメンバと一致します。クライアント コントロールには、Web サーバー コントロール クラス内のメンバに対応しないメンバを指定することもできます。

この例の Web サーバー コントロールは、クライアント コントロールの名前を Samples.SampleTextBox に設定し、クライアント コントロールの highlightCssClass と nohighlightCssClass の 2 つのプロパティを定義します。

クライアント コンポーネントおよびクライアント コントロールを作成する方法の詳細については、「プロトタイプ モデルを使用したクライアント コンポーネント クラスの作成」を参照してください。

クライアント名前空間の登録

クライアント コントロール コードは、まず Type クラスの registerNamespace メソッドを呼び出して、名前空間 (Samples) を登録する必要があります。クライアント名前空間を登録する方法の例を次に示します。

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

クライアント クラスの定義

クライアント名前空間を登録した後、コードは Samples.SampleTextBox クラスを定義します。このクラスには、Web サーバー コントロールによって指定されたプロパティ値を保持する 2 つのプロパティが含まれます。また、Samples.SampleTextBox コントロールに関連付けられた DOM 要素の onfocus イベントおよび onblur イベントのハンドラを指定する 2 つのイベント デリゲートも含まれます。

Samples.SampleTextBox クラス定義の例を次に示します。

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

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

クラス プロトタイプの定義

Samples.SampleTextBox クラスを定義した後、クライアント コードはクラスのプロトタイプを定義します。プロトタイプには、イベント ハンドラだけでなく、プロパティの get アクセサと set アクセサも含まれます。また、コントロールのインスタンスが作成されたときに呼び出される initialize メソッド、およびページでコントロールが不要になったときにクリーンアップを実行する dispose メソッドも含まれます。

DOM 要素のイベント ハンドラの定義

クライアント クラスのイベント ハンドラは、クラス プロトタイプのメソッドとして定義されます。addHandlers メソッドを使用することで、ハンドラはイベント デリゲートおよびブラウザ DOM のイベントに関連付けられます。このメソッドについては、initialize メソッドと共にこのトピックの後半で説明します。

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

プロパティの get メソッドと set メソッドの定義

Web サーバー コントロールの GetScriptDescriptors メソッドの ScriptDescriptor オブジェクトで指定される各プロパティには、対応するクライアント アクセサが必要です。クライアント プロパティ アクセサは、クライアント クラス プロトタイプの get_<property name> メソッドおよび set_<property name> メソッドとして定義されます。

Bb386450.alert_note(ja-jp,VS.90).gifメモ :

JavaScript では大文字と小文字が区別されます。get アクセサ名と set アクセサ名は、Web サーバー コントロール内の GetScriptDescriptors メソッドの ScriptDescriptor オブジェクトで指定されるプロパティ名と完全に一致している必要があります。

Samples.SampleTextBox コントロールのプロパティの get アクセサと set アクセサの例を次に示します。

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

initialize メソッドと dispose メソッドの実装

initialize メソッドは、コントロールのインスタンスが作成されたときに呼び出されます。このメソッドを使用して、既定のプロパティ値の設定、関数デリゲートの作成、およびイベント ハンドラとしてのデリゲートの追加を行います。

Samples.SampleTextBox クラスの initialize メソッドは、次の処理を行います。

  • Sys.UI.Control 基本クラスの initialize メソッドを呼び出します。

  • addHandlers メソッドを呼び出して、関連付けられた HTML 要素 (<input type="text">) の onfocus イベントと onblur イベントのハンドラとしてイベント デリゲートを追加します。イベント名の "on" の部分 (onfocus など) は指定しません。

dispose メソッドは、ページ上でコントロールのインスタンスが使用されなくなり、削除されたときに呼び出されます。このメソッドを使用して、DOM イベント ハンドラなど、コントロールで不要になったリソースを解放します。

Sample.SampleTextBox クラスの dispose メソッドは、次の処理を行います。

  • clearHandlers メソッドを呼び出して、関連付けられた DOM 要素の onfocus イベントと onblur イベントのハンドラとしてイベント デリゲートを消去します。

  • Control 基本クラスの dispose メソッドを呼び出します。

    Bb386450.alert_note(ja-jp,VS.90).gifメモ :

    クライアント クラスの dispose メソッドは、複数回呼び出されることがあります。dispose メソッドに含めるコードがこの可能性を考慮に入れていることを確認します。

Samples.SampleTextBox プロトタイプの initialize メソッドと dispose メソッドを実装する例を次に示します。

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

コントロールの登録

クライアント コントロールを作成する最後のタスクでは、registerClass メソッドを呼び出してクライアント クラスを登録します。クラスはクライアント コントロールであるため、registerClass メソッドの呼び出しには、登録する JavaScript クラス名が含まれます。また、Control を基本クラスとして指定します。

Samples.SampleTextBox コントロールの registerClass メソッドの呼び出しの例を次に示します。この例には、Sys.Application オブジェクトの notifyScriptLoaded メソッドの呼び出しも含まれます。この呼び出しは、JavaScript ファイルが読み込まれたことを Microsoft AJAX Library に通知するために必要です。

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

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

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

テスト用のコントロールの動的コンパイル

このトピックのコントロールも含め、すべての Web サーバー コントロールは、Web ページで参照する前にコンパイルする必要があります。ASP.NET Version 2.0 の動的コンパイル機能を使用すると、Web サーバー コントロールを手動でコンパイルしてアセンブリを生成せずにコントロールをテストできます。これにより、Web サーバー コントロール コードを最初に作成してデバッグするときに時間を短縮できます。次の手順では、App_Code フォルダを使用してコントロールを動的にコンパイルする方法を示します。

動的コンパイルのためにコントロールを App_Code フォルダに配置するには

  1. Web サイトのルート フォルダに App_Code フォルダを作成します。

  2. .cs または .vb コントロール ソース ファイルと、関連するすべてのクラスを App_Code フォルダに移動します。

    または

    以前にこのコントロールのアセンブリを Bin フォルダに追加している場合は、そのアセンブリを削除します。App_Code フォルダ内のソース ファイルの編集を続行します。プロジェクトを実行するたびに、コントロール ソース コードがコンパイルされます。

    Bb386450.alert_note(ja-jp,VS.90).gifメモ :

    コントロールをアセンブリにプリコンパイルして Bin フォルダに配置するか、コントロールのソース ファイルを App_Code フォルダに格納することができますが、両方を行うことはできません。両方のフォルダにコントロールを追加すると、ページ パーサーはページのコントロールへの参照を解決できないため、エラーが発生します。

  3. Web ページを実行します。

    コントロールが動的にコンパイルされます。

動的にコンパイルされたコントロールの Web ページでのテスト

次の手順では、ASP.NET AJAX 対応の Web ページでコントロールをテストする方法について説明します。Web サーバー コントロールのコードは、App_Code フォルダから動的にコンパイルされます。

ASP.NET ページ内で動作を使用するには

  1. 新しい ASP.NET Web ページを作成します。

  2. ページに ScriptManager コントロールがない場合は追加します。

  3. 強調表示されたテキスト ボックスと強調表示されていないテキスト ボックスの CSS スタイル規則を作成します。

    コントロールは、任意の方法で強調表示できます。たとえば、コントロールの背景色の変更、境界線の追加、テキスト フォントの変更などの方法があります。

  4. ページに @ Register ディレクティブを追加し、コントロールの名前空間と TagPrefix 属性を指定します。次に例を示します。

    Bb386450.alert_note(ja-jp,VS.90).gifメモ :

    この例では、サーバー コントロール コードは動的にコンパイルできるように App_Code フォルダに置かれています。したがって、アセンブリ属性は指定しません。

  5. TextBox コントロールと Button コントロールをページに追加し、ID プロパティを設定します。

    コントロールのマークアップには runat="server" を含める必要があります。

  6. FocusExtender コントロールのインスタンスをページに追加します。

  7. FocusExtender コントロールの TargetControlID プロパティを、前の手順で追加した Button コントロールの ID に設定します。

  8. HighlightCssClass プロパティを強調表示の CSS スタイルに設定し、NoHighlightCssClass プロパティを強調表示なしの CSS スタイルに設定します。

  9. ページを実行し、各コントロールを選択します。

    Button コントロールを選択すると、強調表示されます。

このトピックで作成した動作を使用する ASP.NET ページの例を次に示します。

コントロールのアセンブリへのコンパイル

JavaScript コンポーネントと Web サーバー コントロールの拡張コードをアセンブリに埋め込むと、カスタム コントロールの配置が簡単になります。アセンブリの作成により、コントロールのバージョン管理も簡単になります。また、コンパイルしてアセンブリを生成しなければ、コントロールをデザイナのツールボックスに追加することはできません。

次の手順では、Visual Studio を使用して、既存のプロジェクトに新しいコード ライブラリを作成する方法について説明します。コード ファイルのコピーを、このトピック用のプロジェクト内の新しいコード ライブラリに移動します。コード ライブラリでコントロールをコンパイルすると、配置可能なアセンブリが作成されます。

Bb386450.alert_note(ja-jp,VS.90).gifメモ :

この手順を実行するには、Microsoft Visual Studio 2005 を使用する必要があります。Visual Web Developer 2005 Express Edition は使用できません。これは、Visual Web Developer Express Edition を使用すると同じソリューション内に 2 つのプロジェクトを作成できないためです。

既存のプロジェクトに新しいコード ライブラリを追加するには

  1. Visual Studio で、[ファイル] メニューの [新規作成] をクリックし、[プロジェクト] をクリックします。

    [新しいプロジェクト] ダイアログ ボックスが表示されます。

  2. [プロジェクトの種類] で、[Visual C#] または [Visual Basic] を選択します。

  3. [テンプレート] で、[クラス ライブラリ] を選択し、プロジェクトに Samples という名前を付けます。

  4. [ソリューション] の一覧で、[ソリューションに追加] を選択し、[OK] をクリックします。

    既存のソリューションに Samples クラス ライブラリが追加されます。

カスタム サーバー コントロールをコード ライブラリに移動するには

  1. 次の参照を Samples クラス ライブラリ プロジェクトに追加します。この参照は、カスタム サーバー コントロールに必要です。

    • System.Drawing

    • System.Web

    • System.Web.Extensions

  2. ソリューション エクスプローラで、元のプロジェクトから SampleTextBox.cs ファイルまたは SampleTextBox.vb ファイルと SampleTextBox.js ファイルをコピーし、Samples クラス ライブラリ プロジェクトのルートに追加します。

  3. SampleTextBox.js ファイルの [プロパティ] ウィンドウで、[ビルド アクション][埋め込まれたリソース] に設定します。

    スクリプト ファイルを埋め込みリソースに設定

  4. 次のプロパティを AssemblyInfo ファイルに追加します。

    <Assembly: WebResource("Samples.SampleTextBox.js", "text/javascript")>
    
    [assembly: System.Web.UI.WebResource("Samples.SampleTextBox.js", "text/javascript")]
    
    Bb386450.alert_note(ja-jp,VS.90).gifメモ :

    AssemblyInfo.vb ファイルは、ソリューション エクスプローラの [My Project] ノードにあります。[My Project] ノードにファイルが表示されない場合は、[プロジェクト] メニューの [すべてのファイルを表示] をクリックします。AssemblyInfo.cs ファイルは、ソリューション エクスプローラの [プロパティ] ノードにあります。

    JavaScript ファイルの WebResource 定義は、[assembly namespace].[JavaScript File name].js の名前付け規則に従う必要があります。

    Bb386450.alert_note(ja-jp,VS.90).gifメモ :

    Visual Studio では、既定でアセンブリ名前空間がアセンブリ名に設定されます。アセンブリ名前空間は、アセンブリのプロパティで編集できます。

  5. SampleTextBox クラス ファイルで、"Samples" アセンブリに埋め込まれたクライアント コントロール スクリプトを参照するように、GetScriptReferences メソッド内の ScriptReference オブジェクトを変更します。このためには、次の変更を行います。

    • Path プロパティを、"Samples" に設定された Assembly プロパティに置き換えます。

    • Name プロパティを追加し、値を "Samples.SampleTextBox.js" に設定します。

    この変更の結果の例を次に示します。

            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. プロジェクトをビルドします。

    コンパイルが完了すると、Samples.dll という名前のアセンブリが生成されます。JavaScript コード ファイル (SampleTextBox.js) は、このアセンブリにリソースとして埋め込まれます。

    Bb386450.alert_note(ja-jp,VS.90).gifメモ :

    新しいソース ファイルを追加する場合、または既存のソース ファイルを変更する場合は、必ずクラス ライブラリ プロジェクトを再度ビルドしてください。

Web ページ内のアセンブリからのコンパイルされたコントロールの使用

ここで、ASP.NET AJAX 対応の Web ページで、コンパイルしたカスタム コントロールを参照します。

コンパイルしたカスタム コントロールを ASP.NET AJAX 対応の Web ページで参照するには

  1. 新しい ASP.NET AJAX プロジェクトを作成します。

  2. Web サイトのルート ディレクトリに Bin フォルダを作成します。

  3. Samples クラス プロジェクトの Bin\Debug フォルダまたは Bin\Release フォルダから新しい Bin フォルダに Samples.dll アセンブリをコピーします。

  4. TestSampleTextBoxAssembly.aspx という名前の新しい ASP.NET Web ページを追加した後、次のマークアップを新しいページに追加します。

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

    サーバー コントロールのコンパイルによりアセンブリが生成されるため、@ Register ディレクティブには、Namespace 属性と TagPrefix 属性以外に、"Samples" アセンブリを参照する Assembly 属性があります。

  5. ページを実行し、各コントロールを選択します。

    SampleTextBox コントロールを選択すると、強調表示されます。

コンパイルされたカスタム コントロールを使用する Web ページには、@ Register ディレクティブの Assembly 属性が含まれます。それ以外の点では、App_Code フォルダ内のコントロールに使用した Web ページと同じです。

参照

概念

クライアント動作と Web サーバー コントロールとを関連付けるエクステンダ コントロールの作成

ASP.NET UpdatePanel コントロールとデータ バインド コントロールの使用

参照

Sys.UI.Control クラス

IScriptControl

ScriptManager