소개
이 시나리오에서는 페이지의 한 곳에 많은 항목들의 목록을 가지고 있으며(목록은 순서대로 혹은 계층적으로 나열되어야 한다) 이 목록에서의 항목 선택은, 이것과 관련된 모든 세부사항들은 페이지의 다른 한쪽에 보여지게 된다. 이 모든 것은 포스트백과 플리커(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과 콜백 컨트롤을 사용하여 둘 간의 비교와 차이를 배우시케 아주 좋은 경험이 된다.
이렇게 만든 사용자정의 컨트롤은 대단히 유용하다. 초보자조차도 내부동작원리에 대한 많은 지식이 없이도 사용할 수 있다(동일한 페이지에 여러 번 사용할 수 있다). 이 컨트롤은 사용하기 쉽고, 나의 웹 자산에 유용한 도구가 된다! :)
출처 : http://www.codeproject.com/KB/ajax/CallBackCustomControl.aspx
전준호 2009/09/08 00:44
안녕하세요 pdf 파일 보안 걸려있는거 푸시는 방법을 설명 해 놓으셨는데
이해가 잘 안되서 그러는데 jjhtop1@nate.com 으로 메일좀 보내주시면 안될까요?
제가 영어 공부를 할려고 하는데 pdf에서 글이 복사가 안되서 하나씩
타자를 칠려고 하니 너무 번거럽네요 pdf파일 보안 풀수 있는 방법좀 알려주세요
날개달기 2009/09/12 16:24
안녕하세요. 이 글은 프로그래밍을 통해 PDF 파일의 보안을 제거하는 방법을 설명하고 있습니다. 프로그래머를 위한 아티클이죠. 만약 단순하게 프로그램을 통해 PDF 보안을 제거하고 싶으시다면, 관련 프로그램을 설치하시고 실행시키면 됩니다.
stephen 2010/01/14 02:43
안녕하세요. 잘 보았는데요...원래 솔루션파일만 올리신 건가요?
따로 컴파일을 할 수 있는 상황이 아닌데...
실행파일을 올리실 예정은 없는 건가요?
날개달기 2010/01/30 13:52
원래 아티클에 첨부된 파일만 올리고 있습니다. (^ㅡ^)
지옥의단두대 2010/03/14 00:20
덕분에 PDF 보안을 쉽게 제거했네요.
뭐라고 감사의 말씀을 올려야 할지... ㅠ_ㅠ
날개달기 2010/04/06 16:12
도움이 되었다면 그 자체로 만족스럽네요. (^ㅡ^)
나은 2010/03/19 12:43
안녕하세요.
보안이 걸려 있는 일본어 pdf파일을 다운 받았는데, 복사가 안돼서 며칠 전부터 번역하던 중에 다른 방법을 찾다 이 곳을 알게 되었습니다.
보는 즉시 생각도 않고 바로 다운로드 받았는데^^; 파일이 실행이 안되네요..
파일 페이지가 100쪽은 넘는터라 눈앞이 캄캄합니다.
다운로드 받고 그 다음부터 어떻게 해야하는지 방법을 자세하게 알려주시면 안될까요..?
제발 부탁드립니다~
메일은 이쪽입니다. -> im803@hanmail.net
날개달기 2010/04/06 16:14
프로그래머를 위한 글이라 일반인들은 별도의 프로그램을 사용하셔야 합니다. 이와 관련된 프로그램이 있을테니, 검색해보세요. (^ㅡ^)