문서를 읽기에 앞서...
- 이 문서는 영문으로 작성되어 제공되어진 것을 제가 제 나름대로 한글로 번역한 문서입니다.
- 직역보다는 의역에 충실하도록 노력을 하였으며, 충분하게 잘못된 번역이 있을 수 있습니다. 잘못된 번역 부분에 대해서는 덧글로 달아주시면 수정하도록 하겠습니다.
- 이 문서에서 소개한 소스와 제가 받은 소스가 버전이 약간 다르기 때문에 경로가 일치하지 않을 수도 있습니다. 그러나 번역한 문서에 있는 경로에 있는 파일들을 다운로드하여 설치하시면 매뉴얼과 동일하게 설치 및 연습이 가능하실 것입니다.
- 이 문서에는 깔끔하게 번역되지 않은 부분이 있을 수 있습니다. 크게 양해해주시고, 원문을 참조하시기 바랍니다.
- 이 문서는 단지 번역을 한 것 뿐이며, 모든 저작권에 대해서는 영문으로 제공된 원 문서에 있습니다.
- 이 문서에 나와 있는 방법을 바탕으로 코드를 작성하였으나, 제 PC에서는 불가능한 부분이 있었고 이러한 부분은 이 문서의 이미지를 그대로 보여드리고 있습니다.
4.5 드래그 & 드랍의 기능성(functionality)
Introduction : 이 예제를 위해서, "CheckOut.aspx" 페이지에 있는 "Panel1" 컨트롤에 드래그 & 드랍의 기능성을 제공하고 싶어합니다. 그것을 위해서는 "DragOverlayExtender" 컨트롤이 필요합니다.
Step 4.5a : Visual Studio에서 페이지에 있는 "UpdatePanel1"으로 "DragOverlayExtender" 컨트롤을 드래그합니다. "DragOverlayExtender1"의 속성을 다음과 같이 설정합니다.
그림 4.4e : DragOverlayExtender1 컨트롤의 속성들
Test : (쇼핑 카트에 아이템들을 추가하고 필요하다면 로그인을 한 후)"CheckOut.aspx"로 이동합니다. 마우스를 가지고 "Panel1"(베이지/오랜지 배경을 가진)을 움직일 수 있습니다. 그러나, 두 가지 이슈가 있습니다. 컨트롤에 의해서 "Place order"가 숨겨지고 그곳에 그림자(shadow)가 남겨진다는 것입니다. 웹 브라우저를 닫습니다.
이 문제를 제거하기 위해서는 그림자를 제공하는 "Panel1"의 위치가 유지할 것이라고 "DropShadowExtender1"에게 우선적으로 통보(instruct)를 해야할 필요가 있습니다.
Step 4.5b : Visual Studio에서 "Panel1"을 선택하고 "Extenders" 아래으 "DropShadowExtender1"의 속성을 다음과 같이 설정합니다.
"Place Order" 버튼이 다시 보이게 만들기 위해서는, "Panel1"과 "PlaceOrder" 버튼 사이에 11라인의 빈 공간(breaks) (HTML <br />)을 삽입합니다.
Test : "CheckOut.aspx"로 브라우저를 띄웁니다. (베이지/오렌지 배경을 가진) "Panel1"을 따라다니는 그림자가 보일 것입니다. 마찬가지로 "Place Order"는 더 이상 숨어 있지 않습니다.
그러나, 만약 새로고침(F5를 누르면)을 한다면, 초기 위치로 panel이 다시 돌아온다는 것을 주의하십시요. 응용 프로그램은 사용자가 Panel을 이동시킨 위치를 기록하지 않습니다. 우리는 다음 예제에서 이것을 고정시킬 것입니다. 브라우저를 종료합니다.
4.6 AJAX 프레임워크에 있는 ASP.NET의 프로필 서비스를 사용하기
Introduction : 사용자가 "CheckOut.aspx"에 있는 "Panel1" 컨트롤을 움직인 흔적을 남기고자 하기 위해서, ASP.NET AJAX안에 있는 ASP.NET에서 프로필 서비스를 사용할 것입니다.
Step 4.6a : 무엇보다도 우선, ASP.NET AJAX에서 "프로필 서비스"를 포함하고 있는 Web.config를 가져와야 합니다. Authentication 섹션에 아래에 보여지는 코드와 같이 "PanelLocation" 속성을 삽입하고, 프로필 서비스에 자동 저장을 가능하게 해 줍니다.
<system.web.extensions>에서 Authentication과 Profile의 주석을 제거합니다. <profileService> 요소에서, "readAccessProperties"과 "writeAccessProperties" 속성을 "PanelLocation"으로 변경합니다. 이 결과는 다음과 같이 되어야 합니다.
Step 4.6b : "CheckOut.aspx"를 열고, 도구상자에 있는 "AJAX Futures CTP" 탭에 있는 "ProfileService" 컨트롤을 "UpdatePanel1" 컨트롤로 드래그합니다. 다음과 같이 "ProfileService1"을 구성합니다.
(ID) |
ProfileService1 |
AutoSave |
True |
"DragOverlayExtender1" 속성으로 이동하여 다음과 같은 값을 추가합니다.
ProfileProperty |
PanelLocation |
ProfileServiceID |
ProfileService1 |
전에 만들었던 Web.config에서 "PanelLocation" 값은 "DragOverlayExtender1"으로 할당됩니다.
Test : 솔루션을 실행시키고 "CheckOut.aspx"페이지로 이동합니다. 필요하다면 로그인을 합니다. 이제, "Panel1"을 움직인다면, "Panel1"이 그곳에 다시 나타나는지를 주의하여 보십시요. 응용 프로그램은 프로필 서비스에서 각 사용자를 위한 위치와 데이터의 기록을 유지합니다. 브라우저를 종료합니다.
4.7 자신의 ASP.NET AJAX 컨트롤 확장 만들기
Introduction : 바로 앞의 예제에서, ASP.NET AJAX 프레임워크와 AJAX Futures CTP 또는 ASP.NET AJAX Control Toolkit과 함께 샘플로 제공된 것 중의 일부분의 컨트롤만을 사용했습니다. 이 예제에서는, ASP.NET AJAX 클라이언트 스크립트 라이브러리에 도움을 줄 수 있는 새로운 ASP.NET 서버측 컨트롤을 새로 만들 계획입니다. 새로운 컨트롤은 ASP.NET AJAX Control Toolkit에서 쉽게 사용될 것입니다.
새로 만들고자 계획하는 AJAX 확장 컨트롤은 TextBox와 연계된 Button이 TextBox에 아무것도 입력이 되지 않았을 때 Button이 Disabled 되는 향상된 TextBox 컨트롤입니다.
그림 4.7a : 희망하는 상태 (A) : TextBox에 텍스트가 없으면 Button이 Disable된다.
그림 4.7a : 희망하는 상태 (B : TextBox에 텍스트를 입력하자마자 Button이 Enable된다.
Step 4.7a : Visual Studio에서 "Default.aspx"를 엽니다. 페이지의 상위 부분에 "UpdatePanel"을 위치시키고, UpdatePanel안에 "TextBox"와 "Button"컨트롤을 위치시킵니다.
그림 4.7c : 텍스트박스 컨트롤과 버튼 컨트롤이 있는 "Default.aspx"
다음 과정은 동적으로 Button의 선택(enabling)과 선택되지 않는 것(disabling)을 허용하는 클라이언트 측 자바스크립트의 기능을 저장하기 위한 확장 컨트롤을 구축하는 것입니다.
Step 4.7b : "솔루션 탐색기"에서, 프로젝트명을 클릭하고 "파일 -> 추가 -> 새 프로젝트"를 클릭합니다.
다음 대화상자에서, 템플릿 중에서 "ASP.NET AJAX Control Project"를 선택하고 프로젝트명을 "AjaxDisableButton"이라고 합니다.
그림 4.7d : "새 프로젝트 추가" 대화 상자에서 "ASP.NET AJAX Control Project"
솔루션 탐색기에 두 개의 프로젝트가 보입니다. 각 확장 컨트롤은 세 개의 파일로 만들어져 있습니다.
[Projectname]Behavior.js는 실행을 위해서 확장 컨트롤에 의해서 브라우저로 보내진 클라이언트 측 자바스크립트를 포함합니다.
[Projectname]Designer.cs (또는 .vb)와 [Projectname]Extender.cs (또는 .vb) 는 Visual Studio에서 컨트롤을 렌더링을 하기 위해 요구되는 .NET 프레임워크 코드와 서버에서 ASP.NET 컨트롤을 생성하는 것을 포함하고 있습니다.
Step 4.7c : 시작하기 위해서, "AjaxDisableButtonExtender.cs"를 열고 다음과 같이 코드를 수정합니다.
TextBox 컨트롤을 향상시키기 위해서 AjaxDisableButtonExtender 클래스에 있는 [IDReferenceProperty(typeof(Control))] 속성을 [IDReferenceProperty(typeof(Button))]와 같이 변경합니다.
미리 정의된 "MyProperty" 속성을 삭제하고 두 개의 속성인 "TargetButtonID"와 "DisabledText"으로 교체합니다.
"TargetButtonID" 버튼에서 [IDReferenceProperty(typeof(Button))]는 이 속성이 단지 버튼 컨트롤에만 적용될 것임을 가리키는 속성임을 주의해야 합니다.
"AjaxDisableButtonExtender.cs"의 완전한 코드는 다음과 같습니다.
using System;
using System.Web.UI.WebControls;
using System.Web.UI;
using System.ComponentModel;
using System.ComponentModel.Design;
using AjaxControlToolkit;
[assembly: System.Web.UI.WebResource("AjaxDisableButton.AjaxDisableButtonBehavior.js", "text/xxjavascript")]
namespace AjaxDisableButton
{
[Designer(typeof(AjaxDisableButtonDesigner))]
[ClientScriptResource("AjaxDisableButton.AjaxDisableButtonBehavior", "AjaxDisableButton.AjaxDisableButtonBehavior.js")]
[TargetControlType(typeof(TextBox))]
public class AjaxDisableButtonExtender : ExtenderControlBase
{
// TODO: Add your property accessors here.
//
[ExtenderControlProperty]
[IDReferenceProperty(typeof(Button))]
[DefaultValue("")]
public string TargetButtonID
{
get
{
return GetPropertyStringValue("TargetButtonID");
}
set
{
SetPropertyStringValue("TargetButtonID", value);
}
}
[ExtenderControlProperty]
[DefaultValue("")]
public string DisabledText
{
get
{
return GetPropertyStringValue("DisabledText");
}
set
{
SetPropertyStringValue("DisabledText", value);
}
}
}
}
Step 4.7d : "AjaxDisableButtonBehavior.js"를 엽니다. Important : 자바스크립트는 대문자와 소문자를 구별(case-sensitive)합니다. 아래의 코드를 정확하게 지키지 않는다면, 자바스크립트는 변수명을 알아차리지 못할 가능성이 있습니다.
For // TODO : (Step 1) Add your property variables here 다음에 미리 선언된 변수인 "_myPropertyValue"를 다음의 두 변수로 교체합니다.
this._TargetButtonIDValue = null;
this._DisabledTextValue = null;
For // TODO: add your initalization code here 다음에 [안내]태그제한으로등록되지않습니다-xxOnKeyUp EventHandler를 위한 델리게이트를 초기화하는 코드를 추가합니다.
$addHandler(this.get_element(), 'keyup',
Function.createDelegate(this, this._[안내]태그제한으로등록되지않습니다-xxonkeyup));
this._[안내]태그제한으로등록되지않습니다-xxonkeyup();
"dispose" 메소드 뒤에 다음과 같이 "_[안내]태그제한으로등록되지않습니다-xxonkeyup"이라는 새로운 함수를 추가합니다.
_[안내]태그제한으로등록되지않습니다-xxonkeyup : function() {
var e = $get(this._TargetButtonIDValue);
if (e) {
var disabled = ("" == this.get_element().value);
e.disabled = disabled;
if (this._DisabledTextValue) {
if (disabled) {
this._oldValue = e.value;
e.value = this._DisabledTextValue;
} else {
if (this._oldValue) {
e.value = this._oldValue;
}
}
}
}
},
For TODO: (Step 2) Add your property accessors here 다음에 미리 선언된 속성 접근자인 "get_MyProperty"와 "set_MyProperty"를 목적에 맞게 의미있는 속성 접근자로 교체합니다.
get_DisabledText : function() {
return this._DisabledTextValue;
},
set_DisabledText : function(value) {
this._DisabledTextValue = value;
},
get_TargetButtonID : function() {
return this._TargetButtonIDValue;
},
set_TargetButtonID : function(value) {
this._TargetButtonIDValue = value;
}
"AjaxDisableButtonExtender.cs"의 완전한 코드는 다음과 같습니다.
Type.registerNamespace('AjaxDisableButton');
AjaxDisableButton.AjaxDisableButtonBehavior = function(element) {
AjaxDisableButton.AjaxDisableButtonBehavior.initializeBase(this, [element]);
// TODO : (Step 1) Add your property variables here
//
this._TargetButtonIDValue = null;
this._DisabledTextValue = null;
}
AjaxDisableButton.AjaxDisableButtonBehavior.prototype = {
initialize : function() {
AjaxDisableButton.AjaxDisableButtonBehavior.callBaseMethod(this, 'initialize');
// TODO: add your initalization code here
$addHandler(this.get_element(), 'keyup',
Function.createDelegate(this, this._[안내]태그제한으로등록되지않습니다-xxonkeyup));
this._[안내]태그제한으로등록되지않습니다-xxonkeyup();
},
dispose : function() {
// TODO: add your cleanup code here
AjaxDisableButton.AjaxDisableButtonBehavior.callBaseMethod(this, 'dispose');
},
_[안내]태그제한으로등록되지않습니다-xxonkeyup : function() {
var e = $get(this._TargetButtonIDValue);
if (e) {
var disabled = ("" == this.get_element().value);
e.disabled = disabled;
if (this._DisabledTextValue) {
if (disabled) {
this._oldValue = e.value;
e.value = this._DisabledTextValue;
} else {
if (this._oldValue) {
e.value = this._oldValue;
}
}
}
}
},
// TODO: (Step 2) Add your property accessors here
//
get_DisabledText : function() {
return this._DisabledTextValue;
},
set_DisabledText : function(value) {
this._DisabledTextValue = value;
},
get_TargetButtonID : function() {
return this._TargetButtonIDValue;
},
set_TargetButtonID : function(value) {
this._TargetButtonIDValue = value;
}
}
AjaxDisableButton.AjaxDisableButtonBehavior.registerClass('AjaxDisableButton.AjaxDisableButtonBehavior', AjaxControlToolkit.BehaviorBase);
Step 4.7e : 솔루션 탐색기에서 프로젝트명에서 우측 마우스를 클릭하고 확장 컨트롤인 "AjaxDisableButton"의 컴파일을 선택합니다.
"xBikes" 웹 프로젝트에서 우측 마우스를 클릭하여 "참조 추가"를 선택합니다.
그림 4.7e : xBikes 응용 프로그램에서 "AjaxDisableButton" 프로젝트를 참조하기
대화 상자에서 "프로젝트"탭을 선택하고 "AjaxDisableButton" 프로젝트를 선택합니다.
그림 4.7f : 참조 추가 대화 상자
Step 4.7f : 프로젝트는 새로운 확장 컨트롤을 인식하고 있으며 사용할 수 있습니다. 사용하기 위해서 "Default.aspx"를 열고, 화면을 소스 뷰로 전환합니다. 페이지의 상단에 "@Page" 지시자 아래에, 다음과 같이 "@Register" 지시자를 추가합니다.
<%@ Register Assembly="AjaxDisableButton" Namespace="AjaxDisableButton" TagPrefix="demo" %>
이 방법으로, 솔루션은 어셈블리와 확장 컨트롤의 네임스페이스를 인식할 수 있습니다.
솔루션의 모든 파일을 저장합니다.
페이지에 있는 Button 컨트롤 아래에 다음과 같이 AjaxDisableButton 컨트롤을 추가합니다.
<demo:AjaxDisableButtonExtender ID="dbe1" runat="server" />
Visual Studio는 타이핑을 함으로써 네임스페이스와 컨트롤과 인텔리센스를 인식합니다.
그림 4.7g : 인텔리센스는 태그접두사 "demo"를 가지고 네임스페이스를 인식합니다.
페이지의 소스 코드는 다음과 같습니다.
<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" Title="Untitled Page" %>
<%@ Register Assembly="AjaxDisableButton" Namespace="AjaxDisableButton" TagPrefix="demo" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
Welcome to the Downhill Bikes shop!<br />
<br />
<asp:UpdatePanel id="UpdatePanel1" runat="server">
<contenttemplate>
<asp:TextBox id="TextBox1" runat="server"></asp:TextBox>
<asp:Button id="Button1" runat="server" Text="Text found, Button enabled"></asp:Button>
<demo:AjaxDisableButtonExtender ID="dbe1" runat="server" />
</contenttemplate>
</asp:UpdatePanel>
</asp:Content>
Step 4.7g : 좌측 하단 영역에 있는 "디자인" 탭을 클릭하여 디자인 모드로 전환합니다. TextBox와 Button에 관련있는 AjaxDisableButtonExtender 컨트롤을 볼 수 있습니다.
"Button1"의 Text 속성을 다음과 같이 정의합니다.
Text |
Text found. Button enabled. |
AjaxDisableButtonExtender 컨트롤을 아래와 같이 구성합니다.
그림 4.7h : "AjaxDisableButtonExtender" 컨트롤의 구성
TextBox를 선택하고 속성 탭에서 "Extender" 카테고리를 확장합니다.(만약, 이 카테고리가 보이지 않으면 카테고리 뷰 아이콘을 클릭하세요.) 아래와 같이 속성과 값을 설정합니다.
DisabledText |
No text found. Button disabled. |
TargetButtonID |
Button1 |
그림 4.7l : TextBox1의 "Extender" 속성 구성
Test : 브라우저에서 페이지를 엽니다. 빈 TextBox와 선택이 불가능한 Button 컨트롤을 볼 수 있습니다. 만약 TextBox에 글자를 입력하기 시작하면 Button은 즉시 텍스트의 변화에 따라 선택이 가능하게 바뀌게 됩니다. 서버와 주고받는(exchanging) 데이터 없이 작동이 되는 것입니다. 브라우저를 닫습니다.
이로써, 자신만의 ASP.NET 확장 컨트롤을 만들었습니다. 이제, 자바스크립트에서 어떻게 프로그래밍을 해야 하는지를 알고 있는 웹 개발자의 도움 없이도 ASP.NET 응용 프로그램을 사용할 수 있습니다.
- END -
최지훈 [http://www.neostyx.net]
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-동일조건변경허락 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
첫댓글 엔틱스!! 영역을 점점 넓혀 가시는군...
사이트에서도 유명하시더군요..^__^;;
저의 초딩친구 입니다. ㅡㅡ;
유명하다니요...ㅡㅡ;; 이제, 겨우 걸음마를 벗어난 개발자 초급인데요...ㅠㅠ. 많이 도와주십쇼~