다음을 통해 공유


웹 서버 컨트롤에 클라이언트 기능 추가

업데이트: 2007년 11월

ASP.NET의 AJAX 기능을 사용하면 웹 응용 프로그램의 기능을 확장하여 다양한 사용자 경험을 제공할 수 있습니다. 웹 브라우저의 ECMAScript(JavaScript), DHTML 및 AJAX 기능을 사용하여 시각 효과, 유효성 검사와 같은 클라이언트 처리 등을 포함할 수 있습니다.

이 항목에서는 브라우저의 확장된 기능에 ASP.NET의 AJAX 기능을 사용하는 사용자 지정 웹 서버 컨트롤을 만드는 방법을 보여 줍니다. 클라이언트 컨트롤을 사용하여 클라이언트 DOM(문서 개체 모델)에 기능을 추가할 수 있습니다. 서버 컨트롤에서 IScriptControl 인터페이스를 구현하여 클라이언트 컨트롤을 서버 컨트롤에 연결할 수 있습니다.

이 항목에서는 다음과 같은 작업을 수행하는 방법을 배웁니다.

  • 클라이언트 동작을 캡슐화하고 이러한 동작을 제어하기 위해 사용자가 설정할 수 있는 속성을 포함하는 웹 서버 컨트롤을 만듭니다.

  • 웹 서버 컨트롤에 연결하는 클라이언트 컨트롤을 만듭니다.

  • 클라이언트 컨트롤에서 브라우저 DOM의 이벤트를 처리합니다.

    참고:

    또한 Extender 컨트롤을 만들어 웹 서버 컨트롤에 다양한 클라이언트 기능을 추가할 수 있습니다. 이 Extender 컨트롤은 클라이언트 기능을 하나의 동작으로 캡슐화한 다음 웹 서버 컨트롤에 연결될 수 있습니다. Extender 컨트롤은 관련 컨트롤에 포함되지 않으므로 여러 유형의 웹 서버 컨트롤에 연결할 수 있는 하나의 Extender 컨트롤을 만들 수 있습니다. 예제를 보려면 클라이언트 동작을 웹 서버 컨트롤에 연결하는 Extender 컨트롤 만들기를 참조하십시오.

  • 사용자 지정 웹 서버 컨트롤을 어셈블리로 컴파일하고 동일한 어셈블리에 관련 JavaScript 파일을 리소스로 포함합니다.

  • ASP.NET AJAX 사용 웹 페이지에서 컴파일된 사용자 지정 웹 서버 컨트롤을 참조합니다.

클라이언트 요구 사항 식별

웹 서버 컨트롤에 클라이언트 동작을 추가할 때 수행하는 첫 번째 단계는 브라우저에서 구현할 클라이언트의 동작을 결정하는 것입니다. 그런 다음 이러한 동작을 구현하는 데 필요한 클라이언트 기능을 결정합니다.

이 항목에서 만드는 웹 서버 컨트롤에서는 단순한 클라이언트 동작을 구현합니다. 즉, 브라우저에서 컨트롤(TextBox 컨트롤)을 선택하거나 컨트롤에 포커스가 있으면 컨트롤이 강조 표시되는 동작을 구현합니다. 예를 들어 컨트롤에 포커스가 있으면 컨트롤의 배경색이 변경되고 포커스가 다른 컨트롤로 이동하면 기본 색으로 돌아옵니다.

이 동작을 구현하려면 다음 표에서 나열하는 기능이 이 항목의 클라이언트 컨트롤에 필요합니다.

  • DOM 요소를 강조 표시하는 방법
    ASP.NET 웹 페이지에서 DOM 요소를 강조 표시하려면 클라이언트 컨트롤에서 클래스 이름으로 식별되는 CSS 스타일시트 스타일을 적용합니다. 이 스타일은 사용자가 구성할 수 있습니다.

  • DOM 요소를 강조 표시하지 않은 상태로 되돌리는 방법
    ASP.NET 웹 페이지에서 DOM 요소의 강조 표시를 제거하려면 클라이언트 컨트롤에서 클래스 이름으로 식별되는 CSS 스타일시트 스타일을 적용합니다. 이 스타일은 사용자가 구성할 수 있으며 DOM 요소에 기본 스타일로 적용됩니다.

  • DOM 요소가 선택되는 경우를 식별하는 방법
    DOM 요소가 선택되는 경우 즉, 이 요소에 포커스가 있는 경우를 식별하려면 컨트롤에서 DOM 요소의 onfocus 이벤트를 처리합니다.

  • DOM 요소가 선택되지 않은 경우를 식별하는 방법
    컨트롤이 더 이상 선택되지 않은 경우를 식별하려면 컨트롤에서 DOM 요소의 onblur 이벤트를 처리합니다.

웹 서버 컨트롤 만들기

ASP.NET AJAX 기능을 사용하여 클라이언트 기능을 포함하는 웹 서버 컨트롤은 다른 웹 서버 컨트롤과 비슷합니다. 하지만 다른 컨트롤과 달리 이 컨트롤에서는 System.Web.UI 네임스페이스의 IScriptControl 인터페이스도 구현합니다. 이 항목의 컨트롤은 TextBox 클래스를 상속하고 IScriptControl 인터페이스를 구현하여 ASP.NET TextBox 컨트롤을 확장합니다.

다음 예제에서는 클래스 정의를 보여 줍니다.

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

이 새 웹 서버 컨트롤에는 클라이언트 요구 사항을 구현하는 데 사용되는 다음 두 가지 속성이 포함됩니다.

  • HighlightCssClass. 컨트롤에 포커스가 있을 때 컨트롤을 강조 표시하기 위해 DOM 요소에 적용할 CSS 클래스를 식별합니다.

  • NoHighlightCssClass. 컨트롤에 포커스가 없을 때 DOM 요소에 적용할 CSS 클래스를 식별합니다.

IScriptControl 인터페이스 구현

다음 표에서는 웹 서버 컨트롤에서 구현해야 하는 IScriptControl 인터페이스의 멤버를 보여 줍니다.

  • GetScriptDescriptors
    웹 서버 컨트롤에서 사용되는 클라이언트 구성 요소의 인스턴스에 대한 정보를 포함하는 ScriptDescriptor 개체의 컬렉션을 반환합니다. 이러한 정보에는 만들 클라이언트 형식, 할당할 속성, 처리기를 추가할 이벤트가 포함됩니다.

  • GetScriptReferences
    컨트롤에 포함할 클라이언트 스크립트 라이브러리에 대한 정보를 포함하는 ScriptReference 개체의 컬렉션을 반환합니다. 클라이언트 스크립트 라이브러리에서는 클라이언트 형식과 동작에 필요한 기타 JavaScript 코드를 정의합니다.

이 항목의 웹 서버 컨트롤에서는 GetScriptDescriptors 메서드를 사용하여 클라이언트 컨트롤 형식의 인스턴스를 정의합니다. 이 컨트롤에서는 새 ScriptControlDescriptor 개체를 만들고(ScriptControlDescriptor 클래스는 ScriptDescriptor 클래스에서 파생됨) 이 개체를 GetScriptDescriptors 메서드의 반환 값에 포함합니다.

ScriptControlDescriptor 개체는 클라이언트 클래스의 이름(Samples.SampleTextBox)과 웹 서버 컨트롤의 ClientID 값을 포함합니다. 이 값은 렌더링된 DOM 요소의 id 값으로 사용됩니다. 클라이언트 클래스 이름과 ClientID 속성 값은 ScriptControlDescriptor 개체의 생성자에 전달됩니다.

ScriptControlDescriptor 클래스는 클라이언트 컨트롤의 속성 값을 설정하는 데 사용되며, 이러한 속성 값은 웹 서버 컨트롤의 속성에서 가져옵니다. 클라이언트 컨트롤의 속성을 정의하려면 웹 서버 컨트롤에서 ScriptControlDescriptor 클래스의 ScriptComponentDescriptor.AddProperty 메서드를 사용합니다. 그런 다음 웹 서버 컨트롤에서는 클라이언트 컨트롤 속성의 이름과 값을 웹 서버 컨트롤의 해당 속성을 기준으로 지정합니다. 이 예제에서는 ScriptControlDescriptor 개체를 사용하여 클라이언트 컨트롤에서 highlightCssClass 및 nohighlightCssClass 속성의 값을 설정합니다.

웹 서버 컨트롤에서는 GetScriptDescriptors 메서드의 반환 값에 ScriptControlDescriptor 개체를 지정합니다. 따라서 웹 서버 컨트롤이 브라우저에 렌더링될 때마다 ASP.NET에서는 정의된 모든 속성과 이벤트 처리기가 포함된 클라이언트 컨트롤의 인스턴스를 만드는 JavaScript를 렌더링합니다. 이 클라이언트 인스턴스는 웹 서버 컨트롤에서 렌더링된 ClientID 속성을 기반으로 DOM 요소에 연결됩니다. 다음 예제에서는 이 항목의 웹 서버 컨트롤이 페이지에 포함된 선언적 ASP.NET 태그를 보여 줍니다.

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

이 페이지의 렌더링된 출력은 만들 클라이언트를 식별하는 $create 메서드에 대한 호출을 포함합니다. 또한 클라이언트 속성 값과 클라이언트 컨트롤이 연결되는 DOM 개체의 id 값을 제공합니다. 다음 예제에서는 렌더링된 $create 메서드를 보여 줍니다.

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

이 예제의 웹 서버 컨트롤에서는 GetScriptReferences 메서드를 사용하여 클라이언트 컨트롤 형식을 정의하는 스크립트 라이브러리의 위치를 전달합니다. 이 예제에서 이 위치는 뒷부분에서 만들 SampleTextBox.js라는 스크립트 파일의 URL입니다. 이러한 참조를 만들려면 새 ScriptReference 개체를 만든 다음 Path 속성을 클라이언트 코드를 포함하는 파일의 URL로 설정합니다.

다음 예제에서는 GetScriptDescriptorsGetScriptReferences 메서드를 구현하는 방법을 보여 줍니다.

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> 메서드를 호출하고 클라이언트 컨트롤에 대한 참조를 지정합니다.

이 예제 웹 서버 컨트롤은 페이지의 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);
}

다음 예제에는 웹 서버 컨트롤의 전체 코드가 나와 있습니다.

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

클라이언트 컨트롤 만들기

웹 서버 컨트롤에서 GetScriptReferences 메서드는 컨트롤 형식의 클라이언트 코드를 포함하는 JavaScript 파일(SampleTextBox.js)을 지정합니다. 이 단원에서는 해당 파일의 JavaScript 코드를 설명합니다.

클라이언트 컨트롤 코드는 GetScriptDescriptors 메서드에서 반환하는 ScriptDescriptor 개체에서 지정한 멤버와 일치합니다. 클라이언트 컨트롤에는 웹 서버 컨트롤 클래스의 멤버와 일치하지 않는 멤버도 포함될 수 있습니다.

이 예제 웹 서버 컨트롤에서는 클라이언트 컨트롤의 이름을 Samples.SampleTextBox로 설정하고 클라이언트 컨트롤에 대해 highlightCssClass 및 nohighlightCssClass라는 두 가지 속성을 정의합니다.

클라이언트 구성 요소 및 컨트롤을 만드는 방법에 대한 자세한 내용은 프로토타입 모델을 사용하여 클라이언트 구성 요소 클래스 만들기를 참조하십시오.

클라이언트 네임스페이스 등록

클라이언트 컨트롤 코드에서는 먼저 Type 클래스의 registerNamespace 메서드를 호출하여 해당 네임스페이스(Samples)를 등록해야 합니다. 다음 예제에서는 클라이언트 네임스페이스를 등록하는 방법을 보여 줍니다.

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

클라이언트 클래스 정의

클라이언트 네임스페이스가 등록되면 코드에서는 Samples.SampleTextBox 클래스를 정의합니다. 이 클래스는 웹 서버 컨트롤에서 지정한 속성 값을 보유하는 두 개의 속성을 포함하며, Samples.SampleTextBox 컨트롤에 연결되는 DOM 요소의 onfocus 및 onblur 이벤트에 대한 처리기를 지정하는 두 개의 이벤트 대리자도 포함합니다.

다음 예제에서는 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 메서드 정의

웹 서버 컨트롤의 GetScriptDescriptors 메서드에 대한 ScriptDescriptor 개체에서 식별되는 각 속성에는 해당하는 클라이언트 접근자가 있어야 합니다. 클라이언트 속성 접근자는 클라이언트 클래스 프로토타입의 get_<property name> 및 set_<property name> 메서드로 정의합니다.

참고:

JavaScript는 대/소문자를 구분합니다. get 및 set 접근자 이름은 웹 서버 컨트롤에서 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 메서드를 호출합니다.

    참고:

    클라이언트 클래스의 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 라이브러리에 알리기 위해 필요합니다.

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

테스트를 위해 컨트롤을 동적으로 컴파일

이 항목의 컨트롤과 같은 모든 웹 서버 컨트롤을 웹 페이지에서 참조할 수 있으려면 먼저 컴파일해야 합니다. ASP.NET 버전 2.0의 동적 컴파일 기능을 사용하면 컨트롤을 어셈블리로 직접 컴파일하지 않고도 웹 서버 컨트롤을 테스트할 수 있습니다. 이렇게 하면 처음에 웹 서버 컨트롤 코드를 작성하고 디버깅할 때 시간이 절약됩니다. 다음 단계에서는 App_Code 폴더를 사용하여 컨트롤을 동적으로 컴파일하는 방법을 보여 줍니다.

동적 컴파일을 위해 컨트롤을 App_Code 폴더에 추가하려면

  1. 웹 사이트의 루트 폴더 아래에 App_Code 폴더를 만듭니다.

  2. .cs 또는 .vb 컨트롤 소스 파일 및 관련 클래스를 App_Code 폴더로 이동합니다.

    -또는-

    이전에 컨트롤의 어셈블리를 Bin 폴더에 추가한 경우에는 이 어셈블리를 삭제합니다. App_Code 폴더에서 소스 파일을 계속 편집합니다. 컨트롤 소스 코드는 프로젝트를 실행할 때마다 컴파일됩니다.

    참고:

    컨트롤을 어셈블리로 미리 컴파일하여 이 어셈블리를 Bin 폴더에 추가하거나 컨트롤의 소스 파일을 App_Code 폴더에 추가할 수 있지만 이 둘을 모두 수행할 수는 없습니다. 컨트롤을 두 폴더에 모두 추가하면 페이지 파서가 페이지에서 이 컨트롤에 대한 참조를 확인할 수 없으므로 오류가 발생합니다.

  3. 웹 페이지를 실행합니다.

    컨트롤이 동적으로 컴파일됩니다.

웹 페이지에서 동적으로 컴파일된 컨트롤 테스트

다음 절차에서는 ASP.NET AJAX 사용 웹 페이지에서 컨트롤을 테스트하는 방법에 대해 설명합니다. 웹 서버 컨트롤의 코드는 App_Code 폴더에서 동적으로 컴파일됩니다.

ASP.NET 페이지에서 동작을 사용하려면

  1. 새 ASP.NET 웹 페이지를 만듭니다.

  2. 페이지에 ScriptManager 컨트롤이 포함되어 있지 않으면 하나를 추가합니다.

  3. 강조 표시된 텍스트 상자와 강조 표시되지 않은 텍스트 상자에 대한 CSS 스타일 규칙을 만듭니다.

    컨트롤을 원하는 방식으로 강조 표시할 수 있습니다. 예를 들어 컨트롤의 배경색을 변경하거나 테두리를 추가하거나 텍스트 글꼴을 변경할 수 있습니다.

  4. 다음 예제에 표시된 대로 @ Register 지시문을 페이지에 추가한 다음 컨트롤의 TagPrefix 특성 및 네임스페이스를 지정합니다.

    참고:

    이 경우 서버 컨트롤 코드가 동적으로 컴파일될 수 있도록 App_Code 폴더에 있으므로 어셈블리 특성을 지정하지 않습니다.

  5. TextBoxButton 컨트롤을 페이지에 추가하고 해당 ID 속성을 설정합니다.

    컨트롤의 태그에는 를 포함해야 합니다.

  6. FocusExtender 컨트롤의 인스턴스를 페이지에 추가합니다.

  7. FocusExtender 컨트롤의 TargetControlID 속성을 이전에 추가한 Button 컨트롤의 ID로 설정합니다.

  8. HighlightCssClass 속성을 강조 표시 CSS 스타일로 설정하고 NoHighlightCssClass 속성을 강조 표시 안 함 CSS 스타일로 설정합니다.

  9. 페이지를 실행하고 각 컨트롤을 선택합니다.

    Button 컨트롤을 선택하면 컨트롤이 강조 표시됩니다.

다음 예제에서는 이 항목에서 만든 동작을 사용하는 ASP.NET 페이지를 보여 줍니다.

컨트롤을 어셈블리로 컴파일

JavaScript 구성 요소 및 웹 서버 컨트롤의 확장 코드를 어셈블리에 포함하면 사용자 지정 컨트롤을 배포하기가 쉬워집니다. 어셈블리를 만들면 컨트롤의 버전 제어를 관리하기도 쉬워집니다. 또한 어셈블리로 컴파일되지 않은 컨트롤은 디자이너의 도구 상자에 추가할 수 없습니다.

다음 절차에서는 기존 항목 프로젝트에서 Visual Studio를 사용하여 새 코드 라이브러리를 만드는 방법을 설명합니다. 코드 파일의 복사본을 이 항목 프로젝트의 새 코드 라이브러리로 이동합니다. 코드 라이브러리에서 컨트롤을 컴파일하면 배포할 수 있는 어셈블리가 만들어집니다.

참고:

이 절차를 수행하려면 Microsoft Visual Studio 2005를 사용해야 합니다. Visual Web Developer Express Edition에서는 동일한 솔루션에서 두 개의 프로젝트를 만들 수 없으므로 Visual Web Developer 2005 Express Edition을 사용할 수 없습니다.

기존 프로젝트에 새 코드 라이브러리를 추가하려면

  1. Visual Studio 파일 메뉴에서 새로 만들기를 클릭한 다음 프로젝트를 클릭합니다.

    새 프로젝트 대화 상자가 표시됩니다.

  2. 프로젝트 형식 아래에서 Visual C# 또는 Visual Basic을 선택합니다.

  3. 템플릿 아래에서 클래스 라이브러리를 선택하고 프로젝트 이름을 Samples로 지정합니다.

  4. 솔루션 목록에서 솔루션에 추가를 선택한 다음 확인을 클릭합니다.

    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")]
    
    참고:

    AssemblyInfo.vb 파일은 솔루션 탐색기의 My Project 노드에 있습니다. My Project 노드에 파일이 없으면 프로젝트 메뉴에서 모든 파일 표시를 클릭합니다. AssemblyInfo.cs 파일은 솔루션 탐색기의 속성 노드에 있습니다.

    JavaScript 파일에 대한 WebResource 정의는 [assembly namespace].[JavaScript File name].js라는 명명 규칙을 따라야 합니다.

    참고:

    기본적으로 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)은 이 어셈블리에 리소스로 포함되어 있습니다.

    참고:

    새 소스 파일을 추가하거나 기존 소스 파일을 변경하는 경우에는 항상 클래스 라이브러리 프로젝트를 다시 빌드해야 합니다.

웹 페이지의 해당 어셈블리에서 컴파일된 컨트롤 사용

이제 컴파일된 사용자 지정 컨트롤을 ASP.NET AJAX 사용 웹 페이지에서 참조합니다.

사용자 지정 컨트롤을 ASP.NET AJAX 사용 웹 페이지에서 참조하려면

  1. 새 ASP.NET AJAX 프로젝트를 만듭니다.

  2. 웹 사이트의 루트 디렉터리에서 Bin 폴더를 만듭니다.

  3. Samples 클래스 프로젝트의 Bin\Debug 또는 Bin\Release 폴더에서 Samples.dll 어셈블리를 새 Bin 폴더로 복사합니다.

  4. TestSampleTextBoxAssembly.aspx라는 새 ASP.NET 웹 페이지를 추가한 다음 새 페이지에 다음 태그를 추가합니다.

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

    이 서버 컨트롤은 어셈블리로 컴파일되므로 @ Register 지시문에는 Namespace 및 TagPrefix 특성 외에도 "Samples" 어셈블리를 참조하는 Assembly 특성이 있습니다.

  5. 페이지를 실행하고 각 컨트롤을 선택합니다.

    SampleTextBox 컨트롤을 선택하면 컨트롤이 강조 표시됩니다.

컴파일된 사용자 지정 컨트롤을 사용하는 웹 페이지에는 @ Register 지시문에 Assembly 특성이 포함됩니다. 그렇지 않으면 App_Code 폴더의 컨트롤에 사용한 웹 페이지와 동일합니다.

참고 항목

개념

클라이언트 동작을 웹 서버 컨트롤에 연결하는 Extender 컨트롤 만들기

데이터 바인딩된 컨트롤에서 ASP.NET UpdatePanel 컨트롤 사용

참조

Sys.UI.Control 클래스

IScriptControl

ScriptManager