다음을 통해 공유


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

업데이트: 2007년 11월

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

이 자습서에서는 클라이언트 동작을 캡슐화하여 웹 서버 컨트롤에 링크하는 Extender 컨트롤을 만드는 방법을 보여 줍니다. 클라이언트 동작은 브라우저의 DOM(문서 개체 모델) 요소에 기능을 추가합니다. 그런 다음 Extender 컨트롤을 하나 이상의 ASP.NET 서버 컨트롤 형식에 연결하여 이러한 서버 컨트롤에 동작을 추가할 수 있습니다. ASP.NET 서버 컨트롤에 두 개 이상의 Extender 컨트롤을 연결할 수 있습니다.

이 자습서에서는 다음을 수행하는 방법에 대해 알아 봅니다.

  • 클라이언트 동작을 캡슐화하고 ASP.NET 웹 페이지의 웹 서버 컨트롤에 연결하는 Extender 컨트롤을 만듭니다.

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

  • 클라이언트 동작을 사용하여 브라우저 DOM의 이벤트를 처리합니다.

    참고:

    또한 별도의 Extender 컨트롤 없이도 ASP.NET 서버 컨트롤에 다양한 클라이언트 기능을 추가할 수 있습니다. 이 자습서에서 설명하는 것과 동일한 클라이언트 기능을 포함하는 웹 서버 컨트롤을 만드는 방법에 대한 예제는 웹 서버 컨트롤에 클라이언트 기능 추가를 참조하십시오.

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

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

클라이언트 요구 사항 식별

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

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

필요한 기능

구현

DOM 요소를 강조 표시하는 방법

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

DOM 요소를 강조 표시하지 않은 상태로 되돌리는 방법

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

DOM 요소가 선택되는 경우를 식별하는 방법

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

DOM 요소가 선택되지 않은 경우를 식별하는 방법

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

Extender 컨트롤 만들기

ASP.NET 페이지 개발자가 사용할 수 있도록 클라이언트 동작을 캡슐화하기 위해 Extender 컨트롤을 사용할 수 있습니다. Extender 컨트롤은 System.Web.UI 네임스페이스의 ExtenderControl 추상 클래스를 상속하는 웹 서버 컨트롤입니다. Extender 컨트롤은 특정 웹 서버 컨트롤 형식에 적용할 수 있습니다. Extender 컨트롤을 적용할 수 있는 웹 서버 컨트롤 형식을 식별하려면 TargetControlTypeAttribute 특성을 사용합니다.

이 자습서의 Extender 컨트롤은 모든 종류의 웹 서버 컨트롤에 적용할 수 있습니다. 다음 예제에서는 클래스 정의를 보여 줍니다.

<TargetControlType(GetType(Control))> _
Public Class FocusExtender
    Inherits ExtenderControl
[TargetControlType(typeof(Control))]
public class FocusExtender : ExtenderControl

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

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

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

ExtenderControl 추상 클래스 상속

다음 표에서는 Extender 컨트롤에서 구현해야 하는 ExtenderControl 추상 클래스의 멤버를 보여 줍니다.

멤버

설명

GetScriptDescriptors

ECMAScript(JavaScript) 클라이언트 구성 요소를 나타내는 ScriptDescriptor 개체의 컬렉션을 반환합니다. 이러한 정보에는 만들 클라이언트 형식, 할당할 속성, 처리기를 추가할 이벤트가 포함됩니다.

GetScriptReferences

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

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

ScriptBehaviorDescriptor 개체는 클라이언트 클래스의 이름(Samples.FocusBehavior) 및 연결된(대상) 웹 서버 컨트롤의 ClientID 값을 포함합니다. 클라이언트 클래스 이름과 ClientID 속성 값은 ScriptBehaviorDescriptor 개체의 생성자에 제공됩니다. 대상 웹 서버 컨트롤에 대한 참조는 GetScriptDescriptors(Control) 메서드의 매개 변수로 제공됩니다. 이 참조를 사용하여 대상 웹 서버 컨트롤의 ClientID 값 즉, 렌더링되는 DOM 요소의 id 값을 확인할 수 있습니다.

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

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

<asp:TextBox ID="TextBox1"  />
<sample: FocusExtender 
    ID="FocusExtender1" 
    HighlightCssClass="MyHighLight"
    NoHighlightCssClass="MyLowLight"
    TargetControlID="TextBox1" />

이 페이지의 렌더링된 출력은 만들 클라이언트 동작을 식별하는 $create 메서드에 대한 호출을 포함합니다. 또한 클라이언트 동작의 속성 값과 클라이언트 동작이 대상으로 하는 DOM 요소의 id 값을 제공합니다. 다음 예제에서는 렌더링된 $create 메서드를 보여 줍니다.

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

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

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

Protected Overrides Function GetScriptReferences() As IEnumerable(Of ScriptReference)
    Dim reference As ScriptReference = New ScriptReference()
    reference.Path = ResolveClientUrl("FocusBehavior.js")

    Return New ScriptReference() {reference}
End Function

Protected Overrides Function GetScriptDescriptors(ByVal targetControl As Control) As IEnumerable(Of ScriptDescriptor)
    Dim descriptor As ScriptBehaviorDescriptor = New ScriptBehaviorDescriptor("Samples.FocusBehavior", targetControl.ClientID)
    descriptor.AddProperty("highlightCssClass", Me.HighlightCssClass)
    descriptor.AddProperty("nohighlightCssClass", Me.NoHighlightCssClass)

    Return New ScriptDescriptor() {descriptor}
End Function
protected override IEnumerable<ScriptReference> GetScriptReferences()
{
    ScriptReference reference = new ScriptReference();
    reference.Path = ResolveClientUrl("FocusBehavior.js");

    return new ScriptReference[] { reference };
}

protected override IEnumerable<ScriptDescriptor> GetScriptDescriptors(Control targetControl)
{
    ScriptBehaviorDescriptor descriptor = new ScriptBehaviorDescriptor("Samples.FocusBehavior", targetControl.ClientID);
    descriptor.AddProperty("highlightCssClass", this.HighlightCssClass);
    descriptor.AddProperty("nohighlightCssClass", this.NoHighlightCssClass);

    return new ScriptDescriptor[] { descriptor };
}

클라이언트 동작 만들기

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

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

이 자습서의 Extender 컨트롤에서는 클라이언트 동작의 이름을 Samples.FocusBehavior로 설정하고 클라이언트 동작에 대해 highlightCssClass 및 nohighlightCssClass라는 두 가지 속성을 정의합니다.

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

클라이언트 네임스페이스 만들기

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

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

클라이언트 클래스 정의

Samples.FocusBehavior 클래스는 Samples.FocusBehavior 클라이언트 클래스를 정의합니다. 이 클래스는 웹 서버 컨트롤에서 제공한 속성 값을 보유하는 두 개의 속성을 포함합니다.

클래스 프로토타입 정의

Samples.FocusBehavior 클래스를 정의한 후 클라이언트 코드에서는 클래스의 프로토타입을 정의합니다. 프로토타입에는 속성의 get 및 set 접근자와 DOM 요소의 onfocus 및 onblur 이벤트에 대한 이벤트 처리기가 포함되며, 동작 인스턴스를 만들 때 호출하는 initialize 메서드와 페이지에서 동작이 더 이상 필요하지 않을 때 정리를 수행하는 dispose 메서드도 포함됩니다.

DOM 요소의 이벤트 처리기 정의

클라이언트 클래스의 이벤트 처리기는 클래스 프로토타입의 메서드로 정의합니다. addHandlers 메서드를 사용하여 이 처리기를 이벤트 대리자 및 브라우저 DOM의 이벤트에 연결합니다. 이 메서드에 대해서는 이 항목의 뒷부분에서 initialize 메서드와 함께 설명합니다.

속성 Get 및 Set 메서드 정의

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

Initialize 및 Dispose 메서드 구현

initialize 메서드는 동작의 인스턴스를 만들 때 호출합니다. 이 메서드를 사용하여 기본 속성 값을 설정하고 함수 대리자를 만들고 대리자를 이벤트 처리기로 추가할 수 있습니다.

Samples.FocusBehavior 클래스의 initialize 메서드는 다음을 수행합니다.

  • Sys.UI.Behavior 기본 클래스의 initialize 메서드를 호출합니다.

  • addHandlers 메서드를 호출하여 이벤트 대리자를 관련 DOM 요소의 onfocus 및 onblur 이벤트에 대한 처리기로 추가합니다. 이때 이벤트 이름의 "on" 부분(예: onfocus)은 지정하지 않습니다.

dispose 메서드는 페이지에서 동작의 인스턴스를 더 이상 사용하지 않아 제거하는 경우에 호출합니다. 이 메서드를 사용하면 DOM 이벤트 처리기와 같이 동작에 더 이상 필요하지 않은 리소스를 해제할 수 있습니다.

Sample.FocusBehavior 클래스의 dispose 메서드는 다음을 수행합니다.

  • clearHandlers 메서드를 호출하여 관련 DOM 요소의 onfocus 및 onblur 이벤트에 대한 처리기인 이벤트 대리자를 지웁니다.

  • Behavior 기본 클래스의 dispose 메서드를 호출합니다.

    참고:

    클라이언트 클래스의 dispose 메서드는 두 번 이상 호출될 수 있습니다. dispose 메서드에 포함되는 코드에서 이 점을 고려했는지 확인합니다.

동작 등록

클라이언트 동작을 만들 때 마지막 작업은 registerClass 메서드를 호출하여 클라이언트 클래스를 등록하는 것입니다. 클래스가 클라이언트 동작이므로 registerClass 메서드에 대한 호출에서는 등록할 JavaScript 클래스 이름을 포함합니다. 또한 Behavior를 기본 클래스로 지정합니다.

아래의 전체 예제에는 Sys.Application 클래스의 notifyScriptLoaded 메서드에 대한 호출이 포함됩니다. 이 호출은 JavaScript 파일이 로드되었음을 Microsoft AJAX 라이브러리에 알리기 위해 필요합니다.

다음 예제에서는 Samples.FocusBehavior 클라이언트 동작의 전체 JavaScript 코드를 보여 줍니다. 이 자습서의 코드를 사용하려면 JavaScript 파일 이름을 FocusBehavior.js로 지정하여 Script 디렉터리에 두어야 합니다.

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

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

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

//
// Create the prototype for the behavior.
//

Samples.FocusBehavior.prototype = {


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

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

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

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

        Samples.FocusBehavior.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;          
        }
    },


    //
    // Behavior 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.FocusBehavior.descriptor = {
    properties: [   {name: 'highlightCssClass', type: String},
                    {name: 'nohighlightCssClass', type: String} ]
}

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

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

다음 예제에서는 ASP.NET 페이지의 전체 코드를 보여 줍니다.

<html xmlns="http://www.w3.org/1999/xhtml" >
<head >
    <title>ASP.NET AJAX Behavior Sample</title>
    <style type="text/css">
    .LowLight
    {
        background-color:#EEEEEE;
    }

    .HighLight
    {
        background-color:#FFFFF0;
    }
    .LowLightButton
    {
        font-weight:normal;
        width:100px;
    }

    .HighLightButton
    {
        font-weight:bold;
        width:100px;
    }
    </style>
</head>
<body>
    <form id="form1" >
        <asp:ScriptManager ID="ScriptManager1"  />
        <div>
            <table border="0" cellpadding="2">
              <tr>
                <td><asp:Label  ID="Label1" AssociatedControlID="TextBox1">Name</asp:Label></td>
                <td><asp:TextBox ID="TextBox1"  /></td>
              </tr>
              <tr>
                <td><asp:Label  ID="Label2" AssociatedControlID="TextBox2">Phone</asp:Label></td>
                <td><asp:TextBox ID="TextBox2"  /></td>
              </tr>
              <tr>
                <td><asp:Label  ID="Label3" AssociatedControlID="TextBox3">E-mail</asp:Label></td>
                <td><asp:TextBox ID="TextBox3"  /></td>
              </tr>
            </table>

            <asp:Button  ID="Button1" Text="Submit Form" />

            <sample:FocusExtender ID="FocusExtender1" 
                                  NoHighlightCssClass="LowLight"
                                  HighlightCssClass="HighLight"
                                  TargetControlID="TextBox1" />
            <sample:FocusExtender ID="FocusExtender2" 
                                  NoHighlightCssClass="LowLight"
                                  HighlightCssClass="HighLight"
                                  TargetControlID="TextBox2" />
            <sample:FocusExtender ID="FocusExtender3" 
                                  NoHighlightCssClass="LowLight"
                                  HighlightCssClass="HighLight"
                                  TargetControlID="TextBox3" />
            <sample:FocusExtender ID="FocusExtender4" 
                                  NoHighlightCssClass="LowLightButton"
                                  HighlightCssClass="HighLightButton"
                                  TargetControlID="Button1" />
        </div>

    </form>
</body>
</html>

다음 예제에서는 FocusExtender 클래스의 전체 코드를 보여 줍니다. 일반적으로 이 코드는 App_Code 디렉터리에 저장합니다.

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

    <TargetControlType(GetType(Control))> _
    Public Class FocusExtender
        Inherits ExtenderControl

        Private _highlightCssClass As String
        Private _noHighlightCssClass As String

        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 Function GetScriptReferences() As IEnumerable(Of ScriptReference)
            Dim reference As ScriptReference = New ScriptReference()
            reference.Path = ResolveClientUrl("FocusBehavior.js")

            Return New ScriptReference() {reference}
        End Function

        Protected Overrides Function GetScriptDescriptors(ByVal targetControl As Control) As IEnumerable(Of ScriptDescriptor)
            Dim descriptor As ScriptBehaviorDescriptor = New ScriptBehaviorDescriptor("Samples.FocusBehavior", targetControl.ClientID)
            descriptor.AddProperty("highlightCssClass", Me.HighlightCssClass)
            descriptor.AddProperty("nohighlightCssClass", Me.NoHighlightCssClass)

            Return New ScriptDescriptor() {descriptor}
        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
{
    [TargetControlType(typeof(Control))]
    public class FocusExtender : ExtenderControl
    {
        private string _highlightCssClass;
        private string _noHighlightCssClass;

        public string HighlightCssClass
        {
            get { return _highlightCssClass; }
            set { _highlightCssClass = value; }
        }

        public string NoHighlightCssClass
        {
            get { return _noHighlightCssClass; }
            set { _noHighlightCssClass = value; }
        }

        protected override IEnumerable<ScriptReference> GetScriptReferences()
        {
            ScriptReference reference = new ScriptReference();
            reference.Path = ResolveClientUrl("FocusBehavior.js");

            return new ScriptReference[] { reference };
        }

        protected override IEnumerable<ScriptDescriptor> GetScriptDescriptors(Control targetControl)
        {
            ScriptBehaviorDescriptor descriptor = new ScriptBehaviorDescriptor("Samples.FocusBehavior", targetControl.ClientID);
            descriptor.AddProperty("highlightCssClass", this.HighlightCssClass);
            descriptor.AddProperty("nohighlightCssClass", this.NoHighlightCssClass);

            return new ScriptDescriptor[] { descriptor };
        }
    }
}

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

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

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

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

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

    - 또는 -

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

    참고:

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

  3. 웹 페이지를 실행합니다. Extender 컨트롤이 동적으로 컴파일됩니다.

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

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

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

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

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

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

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

  4. 페이지에 @ Register 지시문을 추가한 다음 Extender 컨트롤의 네임스페이스와 TagPrefix 특성을 지정합니다.

    참고:

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

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

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

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

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

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

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

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

  10. FocusExtender 컨트롤의 TargetControlID 속성을 TextBox 컨트롤의 ID로 변경한 다음 페이지를 다시 실행합니다.

    이번에는 TextBox 컨트롤에 포커스가 있을 때 컨트롤이 강조 표시됩니다. FocusExtender 컨트롤에 캡슐화한 동작을 페이지의 여러 ASP.NET 서버 컨트롤에 적용할 수 있습니다. 동작을 여러 컨트롤에 적용하려면 Extender 컨트롤의 여러 인스턴스를 페이지에 추가하고 각 인스턴스를 서로 다른 ASP.NET 서버 컨트롤에 연결할 수 있습니다.

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

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

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

참고:

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

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

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

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

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

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

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

    Samples 클래스 라이브러리가 기존 솔루션에 추가됩니다.

사용자 지정 서버 Extender 컨트롤을 코드 라이브러리로 이동하려면

  1. 사용자 지정 서버 Extender 컨트롤에서 필요한 다음과 같은 참조를 Samples 클래스 라이브러리 프로젝트에 추가합니다.

    • System.Drawing

    • System.Web

    • System.Web.Extensions

  2. 솔루션 탐색기에서 원래 자습서 프로젝트의 FocusExtender.cs 또는 FocusExtender.vb 파일 및 FocusBehavior.js 파일을 Samples 클래스 라이브러리 프로젝트의 루트로 복사합니다.

  3. FocusBehavior.js 파일의 속성 창에서 빌드 작업포함 리소스로 설정합니다.

  4. AssemblyInfo 파일에 다음 속성을 추가합니다.

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

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

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

    참고:

    기본적으로 Visual Studio에서는 어셈블리 네임스페이스를 어셈블리 이름으로 설정합니다. 어셈블리의 속성에서 어셈블리 네임스페이스를 편집할 수 있습니다.

  5. FocusExtender 클래스 파일에서 Samples 어셈블리에 포함된 클라이언트 컨트롤 스크립트를 참조하도록 GetScriptReferences 메서드의 ScriptReference 개체를 변경합니다. 이렇게 하려면 다음과 같이 변경합니다.

    • Path 속성을 "Samples"로 설정된 Assembly 속성으로 바꿉니다.

    • Name 속성을 추가하고 그 값을 "Samples.FocusBehavior.js"로 설정합니다.

    다음 예제에서는 이러한 변경에 따른 결과를 보여 줍니다.

            Protected Overrides Function GetScriptReferences() As IEnumerable(Of ScriptReference)
                Dim reference As ScriptReference = New ScriptReference()
                reference.Assembly = "Samples"
                reference.Name = "Samples.FocusBehavior.js"
    
                Return New ScriptReference() {reference}
            End Function
    
         protected override IEnumerable<ScriptReference> GetScriptReferences()
            {
                ScriptReference reference = new ScriptReference();
                reference.Assembly = "Samples";
                reference.Name = "Samples.FocusBehavior.js";
    
                return new ScriptReference[] { reference };
            }
    
  6. 프로젝트를 빌드합니다.

    컴파일이 끝나면 Samples.dll이라는 어셈블리가 생깁니다. JavaScript 코드 파일(FocusBehavior.js)은 이 어셈블리에 리소스로 포함되어 있습니다.

    참고:

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

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

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

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

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

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

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

  4. TestFocusExtender.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. 페이지를 실행하고 각 컨트롤을 선택합니다.

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

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

참고 항목

개념

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

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

참조

Sys.UI.Behavior Class CTP

ExtenderControl

ScriptManager