-
ASP.NET 서버 컨트롤 개발 기본.NET 정리 2010. 3. 25. 00:30
"ASP.NET 서버 컨트롤은 서버에서 실행되고 사용자 인터페이스 및 기타 관련 기능을 캡슐화하는 구성 요소(컴포넌트)입니다. ASP.NET 서버 컨트롤은 ASP.NET 페이지 및 ASP.NET의 코드 숨김 클래스에서 사용됩니다."라고 설명함
기본 시나리오1.(사용자 정의 컨트롤).
다른 응용 프로그램에서 다시 사용하려는 사용자 인터페이스가 있는 ASP.NET 페이지를 만들었습니다. UI(사용자 인터페이스)를 캡슐화하는 서버 컨트롤을 만들려고 하지만 추가 코드는 작성하지 않으려고 합니다. ASP.NET을 사용하면 한 줄의 코드를 추가로 작성하지 않고도 사용자 정의 컨트롤로 사용자의 페이지를 저장할 수 있습니다.
2.(합성 컨트롤 개발)
둘 이상의 기존 컨트롤의 기능을 조합하는 컴파일된 컨트롤을 개발하려고 합니다. 예를 들어, 단추 및 텍스트 상자를 캡슐화하는 컨트롤이 필요할 수 있습니다. 기존 ASP.NET 서버 컨트롤은 사용자의 요구 사항을 거의 만족시키지만, 그래도 필요한 일부 기능이 부족합니다. 기존 컨트롤에서 파생하고 기존 컨트롤의 속성, 메서드 또는 이벤트를 재정의함으로써 기존 컨트롤을 사용자 지정할 수 있습니다.
3.(서버 컨트롤)
기존 ASP.NET 서버 컨트롤 또는 기존 ASP.NET 서버 컨트롤의 조합은 사용자의 요구 사항을 만족시키지 못합니다. 이 경우에는 기본 컨트롤 클래스 중 하나에서 파생하여 사용자 지정 컨트롤을 만들 수 있습니다. 이 클래스에서는 ASP.NET 서버 컨트롤에서 필요한 모든 핵심 기능을 제공하기 때문에, 사용자는 자신이 필요로 하는 기능을 프로그래밍하는 데 주력할 수 있습니다.
핵심 개념
ASP.NET 서버 컨트롤은 System.Web.UI.Control에서 직접 또는 간접적으로 파생된 클래스입니다. ASP.NET 서버 컨트롤의 기본 클래스는 다음 두 가지가 있다.
System.Web.UI.Control
Control 클래스는 모든 ASP.NET 서버 컨트롤에 공통적으로 사용되는 속성, 메서드 및 이벤트를 정의합니다. 여기에는 컨트롤 실행 주기를 제어하는 메서드와 이벤트 및 ID, UniqueID, Parent, ViewState, Controls(자식 컨트롤의 컬렉션) 등과 같은 속성이 있습니다. Control에는 UI(사용자 인터페이스)의 특정 기능이 없습니다.
UI를 제공하지 않는 컨트롤을 제작하거나, 자신의 UI를 렌더링하는 다른 컨트롤과 조합되는 컨트롤을 제작하려는 경우, Control에서 파생합니다.
System.Web.UI.WebControls.WebControl
WebControl 클래스는 Control에서 파생되며, UI 기능에 대한 추가 속성 및 메서드를 제공합니다. 이 속성에는 ForeColor, BackColor, Font, BorderStyle, Height 및 Width가 있습니다. WebControl은 ASP.NET의 웹 서버 컨트롤 패밀리에 대한 기본 클래스입니다.
사용자의 컨트롤이 UI를 렌더링하는 경우 WebControl에서 파생합니다.
컨트롤의 기능에 따라서 다음 세가지 인터페이스 중 하나 이상를 실행시켜준다.
System.Web.UI.INamingContainer
InamingContainer는 메서드가 없는 빈 표식 인터페이스입니다. 컨트롤이 이 인터페이스를 구현하는 경우, ASP.NET 페이지 프레임워크에서는 해당 컨트롤에서 새 명명 범위를 만듭니다. 이것은 자식 컨트롤이 컨트롤의 계층 구조적 트리에서 고유 ID를 가지도록 보장합니다. 사용자의 컨트롤이 데이터 바인딩을 제공하는 합성 컨트롤(자식 컨트롤을 포함함)이거나 템플릿 기반 컨트롤일 경우 또는 이벤트를 자식 컨트롤로 라우팅해야 할 경우, 이 컨트롤은 INamingContainer 인터페이스를 구현해야 합니다. Repeater 컨트롤 및 기타 데이터 바인딩된 컨트롤을 예로 들 수 있습니다.
(합성 컨트롤 개발)
System.Web.UI.IPostBackDataHandler
사용자의 컨트롤이 게시 데이터를 검사하고 게시 데이터의 상태를 업데이트하거나 데이터의 변경 내용에 따라 서버에서 이벤트를 발생시켜야 하는 경우, 이 컨트롤은 IPostBackDataHandler 인터페이스를 구현해야 합니다. TextBox 컨트롤을 예로 들 수 있으며, 이 컨트롤은 해당 텍스트의 게시된 값을 검사하고, 텍스트가 변경될 때 TextChanged 이벤트를 발생시킬 뿐만 아니라 Text 속성을 업데이트합니다.
(게시 데이터 처리)
System.Web.UI.IPostBackEventHandler
사용자의 컨트롤이 클라이언트측 게시 이벤트를 캡처하고, 클라이언트측 게시 이벤트를 처리하거나 서버에서 이벤트를 발생시켜 응답한 경우, 이 컨트롤은 IPostBackEventHandler 인터페이스를 구현해야 합니다. Button 컨트롤을 예로 들 수 있으며, 이 컨트롤은 폼 전송을 캡처하고 서버에서 Click 이벤트를 발생시킵니다. (게시 이벤트 캡쳐)
컨트롤의 실행 주기
서버는 요청될 때마다 매번 ASP.NET 페이지를 로드한 다음, 요청이 완료되면 해당 ASP.NET 페이지를 언로드합니다. 포함되는 페이지 및 서버 컨트롤은 요청을 실행하고 HTML을 클라이언트로 다시 렌더링해야 합니다. 클라이언트 및 서버 간의 통신이 상태를 저장하지 않고 연결이 끊어져도, 클라이언트에게는 프로세스가 계속 실행되는 것으로 보여야 합니다.
이러한 연속성의 효과는 ASP.NET 페이지 프레임워크 및 페이지와 페이지의 컨트롤에서 만들어집니다. 게시에서 컨트롤은 이전 웹 요청이 종료되어 중단된 부분부터 시작하는 것처럼 동작해야 합니다. 상대적으로 ASP.NET 페이지 프레임워크에서는 상태 관리를 쉽게 수행하지만, 컨트롤 개발자는 연속성의 효과를 얻도록 컨트롤 실행 순서에 주의해야 합니다. 컨트롤 개발자는 컨트롤 실행 주기의 각 단계에서 어떤 정보를 컨트롤에 사용할 수 있는지, 어떤 데이터가 유지되는지, 렌더링 시 컨트롤의 상태가 어떠한지 등에 대하여 이해해야 합니다. 예를 들어, 컨트롤은 페이지에서 컨트롤의 트리가 채워질 때까지 자신의 부모를 호출할 수 없습니다.
아래 표는 컨트롤 실행 주기의 각 단계에 대한 상위 수준 개요입니다.
단계 재정의할 메서드 또는 이벤트 초기화 Init 이벤트(OnInit 메서드) 뷰 상태 로드 LoadViewState 메서드 게시 테이터 처리 LoadPostData 메서드
(IpostBackDataHandler가 구현된 경우)로드 Load 이벤트
(OnLoad 메서드)게시 변경 알림 보내기 RaisePostDataChangedEvent 메서드
(IpostBackDataHandler가 구현된 경우)게시 이벤트 처리 RaisePostBackEvent 메서드
(IpostBackEventHandler가 구현된 경우)사전 렌더링 PreRender 이벤트
(OnPreRender 메서드)상태 저장 SaveViewState 메서드 렌더링 Render 메서드 삭제 Dispose 메서드 언로드 UnLoad 이벤트(On UnLoad 메서드)
참고 EventName 이벤트를 재정의하려면, OnEventName 메서드를 재정의하고 기본 OnEventName을 호출합니다.LoadPostData 및 RaisePostDataChangedEvent는 IPostBackDataHandler 인터페이스의 메서드이며,
RaisePostBackEvent는 IPostBackEventHandler 인터페이스에 속해 있습니다.
사용자의 컨트롤이 게시 데이터 처리를 수행하는 경우, IpostBackDataHandler를 구현해야 합니다.
사용자의 컨트롤이 게시 이벤트를 받아들인 경우, IpostBackEventHandler를 구현해야 합니다.
CreateChildControls 메서드는 표에 나열되지 않았습니다. 왜냐하면 이 메서드는 ASP.NET 페이지 프레임워크에서 컨트롤 트리를 만들어야 할 때마다 호출되어, 이 메서드의 호출이 컨트롤 실행 주기의 특정 단계에 제한되지 않기 때문입니다. 예를 들어, CreateChildControls는 페이지 로드, 데이터 바인딩 또는 렌더링을 수행하는 동안 호출될 수 있습니다.
ASP.NET 서버 컨트롤의 속성
속성은 필드와 유사하지만 접근자 메소드를 가집니다. 속성은 데이터를 숨길 수 있고 버전을 지정할 수 있으며 Visual Studio.NET 등의 비주얼 디자인에서 지원할 수 있으므로,컨트롤의 공용 필드 대신 속성을 노출해야 합니다. 접근자 함수는 속성을 설정하거나 검색할 뿐만아니라 추가 프로그램 논리를 추가할 수 있습니다.
컨트롤에서 상속된 속성
컨트롤이 Control 클래스에서 상속한 속성의 전체 목록은 System.Web.UI.Control을 참조하십시오. 다음 목록에서는 일반적으로 액세스되는 속성 일부를 설명합니다.
Controls - 컨트롤의 자식 컨트롤에 대한 컬렉션
ID - 컨트롤에 대한 사용자 제공 식별자
Page - 컨트롤이 포함된 페이지
Parent - 컨트롤이 속해 있는 Controls 컬렉션의 컨트롤. B가 A.Controls의 요소인 경우 컨트롤 A는 컨트롤 B의 부모가 됩니다.
ViewState - 클라이언트에 보내지고 반환되는 데이터 구조로, 일반적으로 라운드트립에서 폼 데이터를 유지하는 데 사용됩니다. ViewState는 StateBag 형식으로, 이 형식은 데이터를 이름/값 쌍으로 저장하는 사전을 구현합니다.
EnableViewState - 컨트롤이 라운드트립에서 뷰 상태를 유지할지 여부를 나타냅니다. 부모 컨트롤이 자신의 뷰 상태를 유지하지 않는 경우, 자신의 자식 컨트롤에 대한 뷰 상태도 자동으로 유지되지 않습니다.
UniqueID - ASP.NET 페이지 프레임워크에서 컨트롤에 할당한 계층 구조적으로 한정된 고유 식별자.
ClientID - ASP.NET 페이지 프레임워크에서 컨트롤에 할당하고, 클라이언트의 HTML ID 특성으로 렌더링된 고유 식별자. UniqueID에는 콜론(:)이 사용될 수 있기 때문에 ClientID와 UniqueID는 다릅니다. 여기서 콜론은 HTML ID 특성에서 사용할 수 없고, 클라이언트측 스크립트의 변수 이름에 사용할 수 없습니다.
Visible - 컨트롤을 페이지에 표시할지 여부를 결정합니다.WebControl에서 상속된 속성
컨트롤이 WebControl에서 파생된 경우, 해당 컨트롤은 시각적 표시와 관련된 추가 속성을 상속합니다. WebControl에서 상속된 속성의 전체 목록은 System.Web.UI.WebControl을 참조하십시오. 다음 목록에서는 WebControl의 일반적으로 액세스되는 속성 일부를 설명합니다.
Font - 컨트롤의 글꼴.
ForeColor - 컨트롤의 전경색.
BackColor - 컨트롤의 배경색.
Height - 컨트롤의 높이.
Width - 컨트롤의 너비.
Attributes - 클라이언트에 특성으로 렌더링된 이름/값 쌍의 컬렉션. Attributes 속성은 컨트롤의 속성 또는 이벤트에 해당하지 않고 프로그램 방식으로 설정된 선언적 설정 특성들의 집합을 포함합니다.
WebControl은 몇 가지 추가 CSS(cascading style sheet) 스타일을 강력한 형식의 속성으로 노출하기도 합니다.
ASP.NET 서버 컨트롤의 메소드
사용자의 컨트롤은 새 메서드를 정의할 뿐만 아니라 기본 클래스에서 상속된 메서드를 재정의할 수도 있습니다.
컨트롤에서 상속된 메서드 재정의
CreateChildControls 메서드
게시 또는 렌더링하기 위해 자식 컨트롤을 만들도록 합성 컨트롤에 신호를 보냅니다.Dispose 메서드
컨트롤이 최종 정리를 수행할 수 있습니다.LoadViewState 메서드
컨트롤이 상태 정보가 복원되는 방법을 사용자 지정할 수 있습니다.SaveViewState 메서드
다른 웹 요청에서 사용하도록 상태 정보가 유지되는 방법을 컨트롤이 사용자 지정할 수 있습니다.Render 메서드
컨트롤이 클라이언트 브라우저로 내용을 렌더링할 수 있습니다.ASP.NET 서버 컨트롤의 이벤트
데스크톱 응용 프로그램의 이벤트와 달리, ASP.NET 서버 컨트롤 이벤트는 서버에서 처리될 뿐 아니라 서버에서 발생됩니다. 웹 요청이 서버에 클라이언트측 작업을 보내면, 컨트롤은 클라이언트 작업에 응답하여 서버에서 이벤트를 발생시킬 수 있습니다. 이벤트는 페이지 또는 자식 컨트롤에서 처리되며, ASP.NET은 클라이언트에 응답을 보냅니다. 이러한 방식으로 사용자는 데스크톱 응용 프로그램과 유사한 경험을 할 수 있습니다. 그러나 컨트롤 개발자는 하나의 클라이언트측 이벤트만이 서버로 게시되는 게시 이벤트를 이해해야 합니다. 마우스를 클릭하거나 키를 누르는 것과 같은 일반적인 사용자 인터페이스 이벤트는 서버에 보내지지 않기 때문에 서버에서 처리할 수 없습니다.
기본 클래스 System.Web.UI.Control에서는 초기화, 로드 및 언로드와 같은 컨트롤의 실행 주기를 제어하는 이벤트를 제공합니다. 이러한 이벤트가 실행되는 순서는 컨트롤 실행 주기를 참조하십시오. 사용자의 컨트롤에서 추가 이벤트를 발생시킬 뿐만 아니라 이러한 이벤트를 처리할 수도 있습니다.
이벤트 정의
다음 요소에서 이벤트 기능을 제공합니다.
이벤트 데이터가 들어 있는 클래스(예: EventArgs, ImageClickEventArgs 등).
이벤트 대리자(예: EventHandler, ImageClickEventHandler 등).
참고 일반적으로 앞의 두 클래스는 사용자의 컨트롤 외부에서 정의됩니다. 다음 두 멤버는 사용자의 컨트롤에서 정의됩니다.
사용자의 컨트롤에 정의된 이벤트 멤버. 이 이벤트 멤버는 event 키워드로 식별됩니다.
대리자를 호출하는 사용자 컨트롤의 메서드(예: OnClick, OnTextChanged 등).
이벤트 정의와 함께 컨트롤 개발자는 OnEventName 메서드를 호출한 곳에서 이벤트를 발생시키는 방법도 확인해야 합니다. 예를 들어, MyButton은 IPostBackEventHandler의 일부 기능인 RaisePostBackEvent 메서드에서 Click 이벤트를 발생시킵니다.
이벤트 구현의 최적화
상속된 이벤트 처리
상속된 이벤트를 처리하려면, 대리자를 첨부하는 대신 기본 클래스에서 상속된 protected OnEventName 메서드를 재정의합니다. 일반적으로, 재정의된 메서드는 대리자를 호출하지 않으려는 경우 이벤트에 첨부된 대리자가 호출되었는지 여부를 확인하도록 기본 클래스의 OnEventName 메서드를 호출해야 합니다.
ASP.NET 서버 컨트롤이 Control에서 상속하는 이벤트 및 사용자의 컨트롤로 이 이벤트를 처리하려는 경우 재정의할 메서드를 보여 줍니다.
처리할 이벤트 재정의할 메서드 Init OnInit Load OnLoad DataBinding OnDataBinding PreRender OnPreRender UnLoad OnUnLoad 게시 데이터 처리
클라이언트에 의해 다시 게시된 폼 데이터를 검사할 수 있는 컨트롤의 경우에는 System.Web.UI.IPostBackDataHandler 인터페이스를 구현해야 합니다. 이 인터페이스를 사용하면 컨트롤에서 해당 컨트롤의 상태를 다시 게시한 결과로 변경해야 하는지 여부를 확인하여 적절한 이벤트를 발생시킬 수 있습니다. IPostBackDataHandler 인터페이스에는 두 개의 메서드가 있습니다.
public interface IPostBackDataHandler{
public bool LoadPostData(string postDataKey,NameValueCollection postCollection);
public void RaisePostDataChangedEvent();
}게시가 되면, 페이지 프레임워크에서는 IPostBackDataHandler를 구현한 서버 컨트롤의 UniqueID과 일치하는 값을 게시된 내용에서 검색합니다. 그런 다음 해당 인터페이스를 구현한 각 컨트롤에서 LoadPostData를 순서대로 호출합니다. LoadPostData의 두 가지 인수는 컨트롤을 식별하는 키 및 게시된 데이터가 있는 NameValueCollection 컬렉션입니다. 일반적으로 LoadPostData는 컨트롤의 상태를 게시 결과로 업데이트하기 위해 구현됩니다. 다음 예제에서는 사용자 지정 텍스트 상자 컨트롤에 대한 LoadPostData의 구현을 보여 줍니다.
public virtual bool LoadPostData(string postDataKey, NameValueCollection postCollection) {
string presentValue = Text;
string postedValue = postCollection[postDataKey];
if (!presentValue.Equals(postedValue)){
Text = postedValue;
return true;
}
return false;
}컨트롤의 상태가 게시 결과로 변경되면 LoadPostData는 true를 반환하고, 그렇지 않으면 false를 반환합니다. 페이지 프레임워크에서는 true를 반환하는 모든 컨트롤의 트랙을 유지하며 해당 컨트롤에서 RaisePostDataChangedEvent를 호출합니다. 그러면 해당 메서드에서 변경 이벤트(있는 경우)가 발생합니다. 이렇게 게시 데이터는 상태를 업데이트하고 변경 알림을 발생시키는 두 가지 단계로 처리됩니다. 따라서, 모든 컨트롤이 게시 데이터를 로드하기 전에 상태를 잘못 변경할 수 있는 경우, 게시 데이터를 로드하는 동안 변경 알림이 발생하지 않도록 할 수 있습니다. 다음 코드 부분에서는 사용자 지정 텍스트 상자 컨트롤에 대한 RaisePostDataChanged 구현을 보여 줍니다.
public virtual void RaisePostDataChangedEvent() {
OnTextChanged(EventArgs.Empty);
}렌더링 논리에서는 UniqueID를 컨트롤의 이름 특성에 할당해야 합니다. 그렇지 않으면 페이지 프레임워크에서는 게시 데이터를 사용자의 컨트롤에 라우팅할 수 없습니다. 사용자의 컨트롤에서 여러 폼 요소를 내보내는 경우, 최소한 하나의 해당 요소에는 컨트롤의 UniqueID와 일치하는 이름 특성이 있어야 합니다. 여러 폼 필드를 내보내는 사용자 지정 컨트롤에 대한 예제는 컴퍼지션과 렌더링의 비교를 참조하십시오. 다음 코드 부분에서는 이름 특성에 UniqueID를 할당합니다.
protected override void Render(HtmlTextWriter output) {
output.Write("<INPUT type= text name = "+this.UniqueID +
"value = " + this.Text + " >");
}
게시 이벤트 캡처
게시 이벤트를 캡처하는 컨트롤의 경우에는 System.Web.UI.IPostBackEventHandler 인터페이스를 구현해야 합니다. 이러한 인터페이스를 사용하면 컨트롤은 클라이언트의 게시에 응답하여 서버에서 이벤트를 발생시킬 수 있습니다. IPostBackEventHandler 인터페이스에는 하나의 메서드가 있습니다.
public interface IPostBackEventHandler{
void RaisePostBackEvent(string eventArgument);
}게시에 따라 페이지 프레임워크에서는 게시된 내용을 검색하고, 게시된 이름이 IPostBackEventHandler를 구현하는 서버 컨트롤의 UniqueID와 일치하는지 여부를 파악합니다. 일치하는 경우 페이지 프레임워크에서는 변경 이벤트를 발생시킨 후 해당 컨트롤에서 RaisePostBackEvent 메서드를 호출합니다.
다음 코드 부분에서는 서버에서 Click 이벤트를 발생시키는 RaisePostBackEvent의 구현을 보여 줍니다.
public void RaisePostBackEvent(String eventArgument){
OnClick(EventArgs.Empty);
}참고 다음 예제에서처럼 렌더링 논리에서는 UniqueID를 컨트롤의 이름 특성에 할당해야 합니다. 페이지 프레임워크에서는 클라이언트의 이름 특성이 UniqueID와 일치하지 않을 경우 게시 이벤트를 사용자의 컨트롤에 라우팅할 수 없습니다.
protected override void Render(HtmlTextWriter output) {
output.Write("<INPUT TYPE = submit name = " + this.UniqueID +
" Value = 'Click Me' />");
}이벤트 버블링
ASP.NET 페이지 프레임워크에서는 자식 컨트롤이 포함 계층 구조의 상위로 이벤트를 전파할 수 있도록 하는 이벤트 버블링 기술을 제공합니다. 이벤트 버블링을 사용하면 컨트롤 계층 구조의 더 편리한 위치에서 이벤트를 발생시킬 수 있으며, 버블링된 이벤트를 노출하는 컨트롤 뿐만 아니라 원본 컨트롤에도 이벤트 처리기를 연결할 수 있습니다.
항목 템플릿의 자식 컨트롤에서 발생시킨 명령 이벤트를 최상위 이벤트로 노출하기 위해, 이벤트 버블링은 데이터 바인딩된 컨트롤 Repeater, DataList 및 DataGrid에서 사용됩니다. .NET Framework의 ASP.NET 서버 컨트롤이 명령 이벤트(이벤트 데이터 클래스가 CommandEventArgs에서 파생된 이벤트)에 대한 이벤트 버블링을 사용하는 동안, 서버 컨트롤에 정의된 임의의 이벤트는 버블링될 수 있습니다.
컨트롤은 기본 클래스 System.Web.UI.Control에서 상속한 두 개의 메서드를 통해 이벤트 버블링을 수행할 수 있습니다. 이 메서드는 OnBubbleEvent 및 RaiseBubbleEvent입니다. 다음 코드에서는 이러한 메서드의 서명을 보여 줍니다.
protected virtual bool OnBubbleEvent(object source,EventArgs args);
protected void RaiseBubbleEvent(object source,EventArgs args);RaiseBubbleEvent는 Control에 의해 구현되며 재정의될 수 없습니다. RaiseBubbleEvent는 계층 구조 상위에 있는 컨트롤의 부모로 이벤트 데이터를 보냅니다. 버블링된 이벤트를 처리하거나 발생시키려면, 컨트롤은 OnBubbleEvent 메서드를 재정의해야 합니다.
버블링된 이벤트가 있는 컨트롤은 다음 세 항목 중 하나를 수행합니다.
가.이벤트가 부모로 자동 버블링되는 경우에는 아무 처리도 수행하지 않습니다.
나.일부 처리를 수행하며 이벤트 버블링을 계속합니다. 이렇게 수행하려면, 컨트롤은 OnBubbleEvent를 재정의하고 OnBubbleEvent에서 RaiseBubbleEvent를 호출해야 합니다. 데이터에 바인딩된 템플릿 컨트롤 샘플의 다음 코드 부분에서는 이벤트 인수의 형식을 검사한 후 이벤트를 버블링합니다.
protected override bool OnBubbleEvent(object source, EventArgs e) {
if (e is CommandEventArgs) {
// Adds information about an Item to the
// CommandEvent.
TemplatedListCommandEventArgs args =
new TemplatedListCommandEventArgs(this, source, (CommandEventArgs)e);
RaiseBubbleEvent(this, args);
return true;
}
return false;
}다.이벤트 버블링을 중지하고 이벤트를 발생 및/또는 처리합니다. 이벤트를 발생시키면 이벤트를 수신기로 디스패치하는 메서드가 호출됩니다. 버블링된 이벤트를 발생시키려면, 컨트롤은 버블링된 이벤트를 발생시키는 OnEventName 메서드를 호출하도록 OnBubbleEvent를 재정의해야 합니다. 버블링된 이벤트를 발생시키는 컨트롤은 일반적으로 버블링된 이벤트를 최상위 이벤트로 노출합니다. 데이터에 바인딩된 템플릿 컨트롤 샘플의 다음 코드 부분에서는 버블링된 이벤트를 발생시킵니다.
protected override bool OnBubbleEvent(object source, EventArgs e) {
bool handled = false;if (e is TemplatedListCommandEventArgs) {
TemplatedListCommandEventArgs ce = (TemplatedListCommandEventArgs)e;OnItemCommand(ce);
handled = true;
}
return handled;
}이벤트 버블링을 설명하는 샘플은 이벤트 버블링 컨트롤 샘플 및 데이터에 바인딩된 템플릿 컨트롤 샘플을 참조하십시오.
참고 이벤트 버블링을 할 수 있는 메서드 OnBubbleEvent는 이벤트를 발생시키는 메서드의 표준 .NET Framework 명명 패턴을 따르지만, BubbleEvent라는 이름의 이벤트는 없습니다. 버블링된 이벤트는 이벤트 버블링이 중단되는 컨트롤에서 최상위 이벤트로 노출됩니다. 예를 들어, DataList 컨트롤은 ItemCommand 이벤트로 해당 템플릿의 컨트롤에서 Command 이벤트를 노출합니다. .NET Framework의 표준 OnEventName 메서드 서명에는 하나의 인수(protected void OnEventName (EventArgs e))가 있습니다. 그러나 OnBubbleEvent 이벤트는 컨트롤 외부에서 발생하기 때문에 두 개의 인수를 사용합니다. 두 번째 인수는 소스를 제공합니다.
지금까지는 컨트롤이 버블링된 이벤트에 응답하는 방법을 설명하였습니다. 다음 단원에서는 버블링된 이벤트를 정의하는 컨트롤의 제작 방법을 보여 줍니다.버블링된 이벤트 정의
사용자의 컨트롤에서 정의된 이벤트에 대해 이벤트 버블링을 수행할 수 있도록 하려면, 이벤트를 발생시키는 OnEventName 메서드에서 RaiseBubbleEvent를 호출해야 합니다. 컨트롤에서 수행해야 하는 다른 추가 작업은 없습니다. 다음 코드 부분에서는 버블링할 수 있는 Command 이벤트 정의 컨트롤을 보여 줍니다.protected virtual void OnCommand(CommandEventArgs e) {
CommandEventHandler handler = (CommandEventHandler)Events[EventCommand];
if (handler != null)
handler(this,e);// The Command event is bubbled up the control hierarchy.
RaiseBubbleEvent(this, e);
}참고 이벤트 버블링은 명령 이벤트로 제한되지 않습니다. 임의의 이벤트를 버블링하기 위해 여기에 설명된 메커니즘을 사용할 수 있습니다.
ASP.NET 서버 컨트롤 렌더링
렌더링이란 디스플레이 표면에 시각적으로 표시하는 프로세스를 말합니다. 웹 요청의 경우, 실제 렌더링은 클라이언트의 웹 브라우저 또는 기타 보기 장치에서 수행됩니다. ASP.NET 런타임의 기능은 웹 요청에 반응하여 HTML(XML 또는WML 등의 다른 태그 언어에서는 텍스트)을 보내는 것입니다. 페이지 및 자식 컨트롤의 기능은 태그 컨텐트를 출력 스트림에 기록하는 것입니다. 이를 위해 기본 클래스 System.Web.UI.Control에서는 Render 메서드를 제공합니다. 이 메서드에는 다음과 같은 서명이 있습니다.
protected virtual void Render(HtmlTextWriter writer);
System.Web.UI.HtmlTextWriter 클래스는 태그 컨텐트를 기록하기 위해 출력 스트림을 캡슐화합니다. 가장 단순한 형태의 경우, 컨트롤 제작자는 Render를 재정의하고 HTML(또는 기타 태그 컨텐트)을 문자열 인수로 HtmlTextWriter의 Write 메서드에 전달할 수 있습니다.
protected override void Render(HtmlTextWriter output) {
output.Write ("<h3> Hello </h3>");
}HtmlTextWriter에서는 HTML 작성을 간소화해 주는 여러 가지 유틸리티 메서드를 제공합니다. 텍스트 문자열을 Write 메서드에 직접 전달하는 대신 이 메서드를 사용해야 합니다. 그 이유는 이 메서드를 사용하면 코드의 가독성이 향상되고 다시 사용할 수 있으며, 또한 개발자가 세부적인 HTML 구문을 잘 몰라도 되기 때문입니다. 이 유틸리티 메서드의 예제는 HtmlTextWriter 클래스를 참조하십시오. HtmlTextWriter에서는 또한 상향 렌더링 또는 하향 렌더링을 위해 다른 버전의 HTML을 자동 변환해 줍니다.
문자열을 연결하여 하나의 단일 문자열 인수를 Write 메서드에 전달하는 것보다 HtmlTextWriter.Write를 여러 번 호출하는 것이 더 효율적입니다.
참고 간단한 설명을 위해 일부 예제에서는 텍스트 문자열을 HtmlTextWriter.Write로 직접 전달합니다. 하지만 실제 컨트롤에서는 HtmlTextWriter 유틸리티 메서드를 사용해야 합니다.
기본 Control 클래스에서는 자식 컨트롤에서 렌더링이 가능하도록 RenderChildren 메서드를 제공합니다.
protected virtual void RenderChildren(HtmlTextWriter writer);
복합 컨트롤은 RenderChildren 메서드를 호출하기 전과 후에 컨텐트를 렌더링하므로, 자식 컨트롤에서 렌더링되는 컨텐트도 렌더링할 수 있습니다. 다음 코드는 이러한 예제를 나타냅니다.
public class Composite : Control {
...
protected override void Render(HtmlTextWriter writer) {
writer.Write ("My child controls are rendered below.");
RenderChildren(writer);
writer.Write ("My child controls are rendered above.");
}
}기본 Control 클래스에서 Render를 구현하면 항상 RenderChildren이 호출됩니다. 컨트롤의 자식 컨트롤을 렌더링하지 않으려면, 다음 코드와 같이 RenderChildren을 재정의합니다.
protected override void RenderChildren(HtmlTextWriter writer) {
// Do nothing so that child controls are not rendered.
}WebControl의 렌더링 메서드
기본 Control 클래스에서 제공되는 렌더링 메서드 이외에 System.Web.UI.WebControls.WebControl 클래스에서는 쉽게 렌더링을 수행하도록 다른 메서드를 제공합니다.AddAttributesToRender 메서드에서는 WebControl에서 파생된 컨트롤을 사용하여 추가 HTML 특성 및 CSS 스타일시트의 스타일을 렌더링하도록 지정할 수 있습니다. 다음 예제는 단추 컨트롤을 사용하여 특성을 출력 스트림에 기록하는 방법을 나타냅니다. base.AddAttributestoRender를 호출하면 기본 클래스에 의해 렌더링된 특성이 보존된다는 점에 주목합니다.
protected override void AddAttributesToRender(HtmlTextWriter writer) {
writer.AddAttribute(HtmlTextWriterAttribute.Type, "submit");
writer.AddAttribute(HtmlTextWriterAttribute.Name, UniqueID);
writer.AddAttribute(HtmlTextWriterAttribute.Value, Text);
base.AddAttributesToRender(writer);
}RenderBeginTag 및 RenderEndTag 메서드에서는 WebControl에서 파생된 컨트롤을 사용하여 HTML 요소의 시작 태그와 끝 태그를 재정의할 수 있습니다. RenderContents 메서드에서는 컨트롤을 사용하여 태그 내에 컨텐트를 지정할 수 있습니다.
참고 웹 서버 컨트롤(WebControl에서 파생된 클래스)의 출력 스트림에 텍스트를 기록하기 위해서는 Render 메서드를 직접 재정의하는 대신 RenderContents 메서드를 재정의해야 합니다. 그러면 WebControl에서 구현된 렌더링 기능(예: 특성 생성 기능)을 보존할 수 있습니다.
컨트롤에서 상태 관리
ASP.NET 서버 컨트롤은 ViewState라는 속성을 Control에서 상속합니다. ASP.NET 서버 컨트롤은 이 속성을 사용하여 상태 관리에 쉽게 관여할 수 있습니다. ViewState의 형식은 System.Web.UI.StateBag이며, 이것은 이름/값 쌍이 저장되어 있는 사전입니다. ViewState는 ASP.NET 페이지 프레임워크에 의해 문자열 변수로 지속되다가, 클라이언트에 보내지고 숨겨진 변수로 다시 돌아옵니다. 다시 게시하는 동안, 페이지 프레임워크는 숨겨진 변수에 입력된 문자열을 분석하고 각 컨트롤의 ViewState 속성을 채웁니다. 컨트롤에서 속성 데이터에 전용 필드 대신 ViewState 속성을 사용하는 경우, 이 속성은 클라이언트로 라운드트립하는 동안 자동으로 지속될 것입니다. 속성이 ViewState에서 지속되지 않는 경우, 다시 게시하는 동안 기본 값을 반환하는 것이 좋습니다.
다음 코드는 ViewState에 저장된 속성을 나타냅니다.
public String Text {
get {
return (String) ViewState["Text"];
}
set {
ViewState["Text"] = value;
}
}ViewState를 사용하여 속성을 저장하는 예제는 ASP.NET 퀵 스타트 > ASP.NET 웹 폼 > 사용자 지정 컨트롤 제작을 참조하십시오.
참고 일반적으로 ViewState는 라운드트립 중에 페이지 상의 형식 데이터를 지속시키는 데 사용됩니다. 암호, 연결 문자열, 파일 경로 등의 정보를 저장하기 위해 ViewState를 사용해서는 안됩니다. 페이지 또는 더 지속적인 저장소 상에서 데이터를 공유하는 방법은 ASP.NET 상태 관리를 참조하십시오.
ViewState에서 지속될 수 있는 형식
Serialize할 수 있는 형식 또는 TypeConverter가 정의된 형식은 ViewState에서 지속될 수 있습니다. 하지만, serialize만 할 수 있는 형식은 속도가 더 느리고, TypeConverter를 정의하는 것보다 훨씬 큰 ViewState를 생성합니다. 제한된 개체 serialization 형식을 사용하여 ViewState를 serialize할 수 있습니다. 이 형식은 기본 형식과 String, ArrayList 및 Hashtable 형식에 맞게 최적화되어 있습니다.ViewState 및 성능
컨트롤 개발자는 ViewState의 모든 데이터가 클라이언트로 자동 라운드트립된다는 사실을 알아야 합니다. 이 라운드트립은 성능 오버헤드에 영향을 미치므로, ViewState를 신중하게 사용하는 것이 중요합니다. 여러 속성에서 공용 데이터를 사용하는 경우, 키 요소만을 ViewState에 지속시켜서 성능을 최적화할 수 있습니다. 컨트롤은 EnableViewState라는 속성을 Control에서 상속합니다. 컨트롤 사용자는 이 속성을 사용하여 ViewState의 지속성을 설정하거나 해제할 수 있습니다.ViewState를 사용하여 상태 복원 사용자 지정
효율성을 향상시키고 또한 기본적으로 ViewState에 저장할 수 없는 사용자 지정 형식을 저장하기 위해, 컨트롤에서는 속성 데이터를 ViewState에 저장하는 방법을 사용자 지정할 수 있습니다. 컨트롤에서 속성 데이터 저장을 사용자 지정하는 경우, 이 컨트롤에서는 또한 ViewState에 저장된 데이터에서 속성 값을 복원하는 데 필요한 사용자 지정 구현을 제공해야 합니다. 기본 Control 클래스에서는 이 구현을 위해 SaveViewState 및 LoadViewState의 두 메서드를 제공합니다. 이 메서드에는 다음과 같은 서명이 있습니다.protected virtual object SaveViewState();
protected virtual void LoadViewState(object savedState);
컨트롤 분석, ParseChildrenAttribute 및 컨트롤 작성기컨트롤에서는 사용자 지정 메타데이터를 제공할 수 있습니다. 이 메타데이터는 컨트롤이 ASP.NET 페이지 상에서 선언적으로 사용되는 경우, 컨트롤 태그 내의 중첩된 (자식) 요소를 변환하는 방법을 ASP.NET 페이지 분석기에 알려 줍니다. 이를 위해 .NET Framework에서는 다음과 같은 두 특성 클래스를 제공합니다.
ParseChildrenAttribute 클래스는 컨트롤 태그 내의 중첩된 (자식) 요소가 속성으로 변환되는지를 지정합니다. 이 특성을 사용하는 자세한 방법은 ParseChildrenAttribute 사용을 참조하십시오.
ControlBuilderAttribute 클래스는 컨트롤 작성기 클래스와 컨트롤을 연결하여 더 복잡한 분석 논리를 사용할 수 있도록 합니다.
참고 이 두 특성은 함께 사용될 수 있습니다. 따라서 동일한 컨트롤에 ParseChildrenAttribute 및 ControlBuilderAttribute가 동시에 적용될 수 있습니다.'.NET 정리' 카테고리의 다른 글
ASP.NET 2.0의 마스터 페이지 (0) 2010.04.01 테마 (0) 2010.04.01 표준컨트롤 예시 (0) 2010.03.18 ASP.NET 표준컨트롤 - Panel, MultiView, Wizard (0) 2010.03.11 APS.NET 표준컨트롤 (0) 2010.03.04