소개
이 시나리오에서는 페이지의 한 곳에 많은 항목들의 목록을 가지고 있으며(목록은 순서대로 혹은 계층적으로 나열되어야 한다) 이 목록에서의 항목 선택은, 이것과 관련된 모든 세부사항들은 페이지의 다른 한쪽에 보여지게 된다. 이 모든 것은 포스트백과 플리커(flicker) 없이도 사용자에게 부드럽고 좋은 느낌을 주어야 한다.
예를 들어, 웹 어플리케이션과 관련된 자산(finance)을 가지고 있다. 포트폴리오 내의 stock 스크립트에 관련된 세부사항들을 봐야한다(상당한 스크립트들이 동일한 페이지에 기재되어 있다). 지금 현재 스크립트가 선택되었고, 모든 세부사항들과 스크립트의 현재 상태는 어떠한 포스트백이나 플리커 없이 동일한 페이지에 보여진다.
여기서, 위에 언급한 시나리오는 ASP.NET 2.0에서 소개된 클라이언트 콜백 기능을 사용하면 된다. 이렇게 쉽게 사용할 수 있는 사용자정의 컨트롤 내에 삽입될 수 있는 이러한 기능과 관련된 상당한 코드를 발견했다. 더욱이, 페이지에서 콜백을 여러 번 사용한다면, 상당한 코드를 줄여야 한다. 그래서, 나는 클라이언트 콜백 기능을 사용하기 위해 "사용자 친화적인" 사용자정의 컨트를 개발하려고 한다.
배경
이 프로젝트에서, 다른 부분을 조작하는 곳은 범주화되어 있다(범주 내에서의 계층적 구조 때문에, 트리 뷰 컨트롤로 결정하였다). 한 곳에서의 선택(노드)을 통해, 동일한 페이지에 있는 그리드 내에 관련된 상태와 자료를 보여주려고 한다. 성능은 고객의 주요 요구 사항들 가운데 하나다. 그래서, 그 요구를 충족시키기 위해, 클라이언트 콜백 기능을 사용하기로 결정했다. 이 예제는 이러한 경험에 기반을 두고 있다.
코드사용
먼저, 사용자정의 컨트롤의 중요한 코드 부분들:
WebControl에서 상속받고, 또한 ICallbackEventHandler 에서 상속받는다.
public class MyCustomCallBackControl : WebControl, ICallbackEventHandler {}
컨트롤의 OnInit() 메서드는 재정의하였다. 이 컨트롤에 대한 콜백 스크립트는 다음과 같이 삽입되어 있다.
// OnInit was overriden in order to attach a callback handler to the control
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
string callback = Page.ClientScript.GetCallbackEventReference(this, "input",
string.Concat(ID, "OnSuccess"), "context");
Page.ClientScript.RegisterClientScriptBlock(typeof(MyCustomCallBackControl),
ID, string.Concat("function ", ID,
"Callback(input, context) { ", callback, "; }"), true);
//Above line - Script added during runtime:
//function MyCustomCallBackControl1Callback(input, context)
//{
// WebForm_DoCallback('MyCustomCallBackControl1',
// input,MyCustomCallBackControl1OnSuccess,context,null,false);
//}
//General meaning of it:
// WebForm_DoCallback(eventTarget, eventArgument, eventCallback,
// context, errorCallback, useAsync)
}
ICallbackEventHandler 인터페이스 구현과 관련된 GetCallBackResult과 RaiseCallBackEvent 메서드를 작성해야 한다.
// Event handler for code logic at server side on client-callback
// Event bubbling done here
public event EventHandler MyCallBackEvent;
public void RaiseCallbackEvent(string eventArgument)
{
argumentParameter = eventArgument;
if (MyCallBackEvent != null)
{
MyCallBackEvent(this, EventArgs.Empty);
}
}
public string GetCallbackResult()
{
//Returns back the output set during the callback
return renderedOutput;
}
이제 클라이언트 콜백 사용자정의 컨트롤을 사용할 준비가 되었다.
이제는 웹 페이지에서 이 컨트롤을 사용하는 방법을 보여주도록 하겠다. 페이지에 컨트롤을 갖다 놓고, 코드 비하인드 핸들러(code-behind handler)를 정의하는데, 기본적으로, 서버 코드는 콜백 컨트롤이 호출될 때 실행된다.
// Bubbled event for Callback control placed
// One can handle the operations required during the callback out here.
protected void CallBackControl_Perform(object sender, EventArgs e)
{
DataTable dt = RetrieveDataTable(((
MyCustomControls.MyCustomCallBackControl)sender).ArgumentParameter);
gvTest.DataSource = dt;
gvTest.DataBind();
//Setting of the response output for callback
using (System.IO.StringWriter sw = new System.IO.StringWriter())
{
gvTest.RenderControl(new HtmlTextWriter(sw));
((MyCustomControls.MyCustomCallBackControl)sender).RenderedOutput = sw.ToString();
}
}
이 예제에서는, 이 콜백 컨트롤에 세 노드를 바인딩하도록 하겠다. 이 작업은 자바스크립트를 사용하면 된다.
//Client Side callback event attached
tNode.NavigateUrl = "javascript:OnNodeClick('" + tNode.Value + "');";
이젠 사용자정의 콜백 컨트롤에 첨부된 자바스크립트 함수들의 정의를 남겨두었다. 이 함수들은 위에 정의된 OnNodeClick 메서드 안에 바인딩된다.
//Node Callback Click Event
function OnNodeClick(nodeID)
{
// Method name to call has a fixed naming convention
// CustomCallbackControl name + "Callback"
// Parameters to the function would be:
// 1st : Input
// 2nd : Context
MyCustomCallBackControl1Callback(nodeID, null);
}
// Function name has a fixed naming convention
// CustomCallbackControl name + "OnSuccess"
function MyCustomCallBackControl1OnSuccess(responseText)
{
// Based on responseText, action taken on client side
document.getElementById("tdGridView").style.display = "block";
document.getElementById("gvTest").outerHTML = responseText;
}
이제 이 컨트롤에 대한 사용을 마무리하였다. 자바스크립트 함수들을 위한 명명 규칙(naming conventions)이 정의되었고, 이에 맞춰 작성해야 한다.
흥미로운 점
성능은 실제로 좋은데, 아주 간편하고 미끈한 UI는 아주 훌륭하다. 이것은 UpdatePanel과 콜백 컨트롤을 사용하여 둘 간의 비교와 차이를 배우시케 아주 좋은 경험이 된다.
이렇게 만든 사용자정의 컨트롤은 대단히 유용하다. 초보자조차도 내부동작원리에 대한 많은 지식이 없이도 사용할 수 있다(동일한 페이지에 여러 번 사용할 수 있다). 이 컨트롤은 사용하기 쉽고, 나의 웹 자산에 유용한 도구가 된다! :)
출처 :
CustomClientCallBackEx.zip


