본문 바로가기

study

ASP.net With C Shap Chapter 2 [훈스닷넷 강좌 펌]


  강좌 최초 작성일 : 2004년 04월 01일
  강좌 최종 수정일 : 2004년 08월 17일 

  작성자 : YouKnow(문윤호) 
youknow@fuz.co.kr
  편집자 : HOONS(박경훈) http://www.hoonsbara.com

  강좌 제목 : ASP.NET Summary Ver.2 Chapter2 (웹폼 생성및 서버 컨트롤의 사용)
 


-. 웹 폼으로 페이지를 생성하고 Html 컨트롤 및 웹 서버 컨트롤을 사용해 보자.

    1. 웹 폼(HelloCsharp.aspx)을 생성하자.
    이 페이지는 코드 비하인드(CS파일) 작업을 하지 않고, 스크립트 처리하는 부분을 볼것이다. 웹폼에 TextBox, Button 웹 컨트롤을 추가하고, Html 모드에서 C# 스크립트를 작성하여 컨트롤에 연결한다.

<script language="C#" runat="server">
    public void btnOK_Click(Object sender, System.EventArgs e)
    { txtMessage.Text = "Hello, C#!"; }
    </script>

    <HTML>
        <HEAD>
            <title>WebForm1</title>
            <meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
            <meta name="CODE_LANGUAGE" Content="C#">
            <meta name="vs_defaultClientScript" content="JavaScript">
            <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
        </HEAD>

        <body MS_POSITIONING="GridLayout">
            <form id="Form1" method="post" runat="server">
                <asp:TextBox ID="txtMessage" unat="server"></asp:TextBox>
                <asp:Button ID="btnOK" Runat="server" Text="확인" OnClick="btnOK_Click"></asp:Button>
            </form>
        </body>

    </HTML>

    코드 작성이 완료 되었으면 디자인 모드에서 오른쪽 버튼을 클릭한 후 '브라우저에서 보기' 선택하면 자동으로 컴파일 후 브라우저가 열리면서 실행 될 것이다. 실행되면 Button Control을 클릭해 보자. TextBox Control에 'Hello, C#!' 찍히는 것을 확인 할 수 있을 것이다.

    2. 웹 폼(Hello.aspx)을 생성하자.
     이 페이지에선 코드 비하인드 작업을 실행하여 TextBox에 글자를 찍어 볼 것이다. 웸 폼에 TextBox, Button Control을 상기와 동일하게 추가하고, Button Control의 이벤트 중 클릭 이벤트를 발생 시키자. 이벤트는 해당 컨트롤의 속성창 중 이벤트 속성창이 있으며 거기에서 처리하고자 하는 이벤트를 더블 클릭하면 코드 비하인드 소스(CS파일)에 자동 추가 된다. 여기에서 확인할 수 있는 것은 Page 지시어 이다. 어느 Codebehind 소스와 연결 되었는지 어느 클래스에서 상속 받는지를 지정한다. Page 지시어(Directive)라고 하는데 컴파일러에게 적절한 언어 컴파일러에 대한 정보 외에 여러 속성으로 페이지의 특성을 지정할 수 있다.  
Codebehind="Hello.aspx.cs" Complie전에 필요, Inherits="WebTest.Hello" WebTest : NameSpace(어셈블리명), Hello : Class(클래스명)
    

<%@ Page language="c#" Codebehind="Hello.aspx.cs" AutoEventWireup="false" Inherits="WebTest.Hello" %>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >

    <HTML>
        <HEAD>
            <title>Hello</title> 
            <meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
            <meta name="CODE_LANGUAGE" Content="C#">
            <meta name="vs_defaultClientScript" content="JavaScript">
            <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
        </HEAD>

        <body ms_positioning="GridLayout">
            <form id="Form1" method="post" runat="server">
                <asp:TextBox id="TextBox1" style="Z-INDEX: 101; LEFT: 16px; POSITION: absolute; TOP: 24px" runat="server"></asp:TextBox>
                <asp:Button id="Button1" style="Z-INDEX: 102; LEFT: 184px; POSITION: absolute; TOP: 24px" runat="server" Text="Button"></asp:Button>
            </form>
        </body>

    </HTML>

(소스) Hellow.aspx

    Html 소스 코드 작성이 완료 되면, CS 파일에 필요한 기능을 작업해 보자. 여기서 확인할 것은 디자인 모드에서 추가한 Control이 클래스의 멤버로 추가 되었음을 확인할 수 있고, Button Click 이벤트가 InitializeComponent 메소드에 자동 추가 되었음을 확인 할 수 있다. Button Control Click 이벤트의 위임자 메소드는 Button1_Click 이며, 클릭시 TextBox의 Text에 'Hello, C#!' 대입시킨다.

using System;
    using System.Collections;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Web;
    using System.Web.SessionState;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.HtmlControls;
    namespace WebTest
    {
        /// <summary>
        /// Hello에 대한 요약 설명입니다.
        /// </summary>
        public class Hello : System.Web.UI.Page  // Page Class를 상속 는다.
        {
            protected System.Web.UI.WebControls.TextBox TextBox1;
            protected System.Web.UI.WebControls.Button Button1;

            private void Page_Load(object sender, System.EventArgs e)
            { // 여기에 사용자 코드를 배치하여 페이지를 초기화합니다. }

            #region Web Form 디자이너에서 생성한 코드
            override protected void OnInit(EventArgs e)
            {
                // CODEGEN: 이 호출은 ASP.NET Web Form 디자이너에 필요합니다.
                InitializeComponent();
                base.OnInit(e);
            }
            /// <summary>
            /// 디자이너 지원에 필요한 메서드입니다.
            /// 이 메서드의 내용을 코드 편집기로 수정하지 마십시오.
            /// </summary>
            private void InitializeComponent()
            {    
                this.Button1.Click += new System.EventHandler(this.Button1_Click);
                this.Load += new System.EventHandler(this.Page_Load);
            }

            #endregion

            private void Button1_Click(object sender, System.EventArgs e)
            {
                TextBox1.Text = "Hello, C#!";
            }
        }
    }

 

(소스)Hellow.aspx.cs

   코드 비하인드 에서 한가지 짚고 넘어가야 할 것은 컨텐츠부인 *.aspx 파일과 코드부인 *.aspx.cs 파일의 관계이다. 나란하게 짝으로 존재하기 때문에 수평적인 관계라고 이해하는 분들이 많다. 하지만 실제는 그렇지 않다. *.aspx 파일은 x.aspx.cs로 부터 클래스를 상속받는 수직적인 관계이다.

    이벤트 모델 : 웹 폼에서 대부분의 이벤트는 클라이언트에서 발생하고 처리는 웹 서버가 담당한다. (Calendar나 AdRotator 웹 컨트롤의 경우에는 서버상에서 이벤트가 발생한다.) 클라이언트에서 발생한 이벤트를 처리하기 위해서 웹 폼 이벤트 모델은 클라이언트의 이벤트 정보를 감지하고 이벤트 메시지는 서버로 전송된다. 이러한 웹에서의 동작은 HTTP POST를 통해 이뤄져야만 한다. 웹 폼 프레임워크는 어떤 이벤트가 발생했는지 판단하기 위해서 POST 정보를 해석해야 하며 그 후 이벤트를 처리하기 위해 작성한 코드에서 적절한 메소드를 호출한다.

    페이지(Page) 이벤트 : Page 객체가 읽혀질 때마다 Page_Load 이벤트가 발생하며 이 이벤트에 대한 핸들러를 작성함으로써 페이지 초기화 작업을 수행할 수 있다. 예를 들어 이 이벤트내에서 데이터베이스를 쿼리문을 실행하여 결과를 페이지에 반영하는 데 사용할 수 있다. 그리고 페이지의 모든 작업을 수행한 뒤에는 Page_Unload 이벤트가 발생한다. 이는 마치 객체지향 프로그래밍에서 클래스 생성자(constructor)와 소멸자(destructor)의 역할과 비슷하다.

    Page.IsPostBack 프로퍼티 : Page_Load 이벤트는 페이지가 읽혀질 때마다 발생하기 때문에 그 때마다 페이지를 초기화 하는 작업을 수행하는 것은 낭비일 수 있다. Page 클래스는 IsPostBack이라는 불린(Boolean)형 프로퍼티를 제공하는데 이 값이 True면 해당 페이지는 이미 렌더링된 페이지가 사용자에 의해서 다시 호출된 것을 의미한다. Page 클래스의 IsPostBack의 값이 True일 때에는 데이터베이스를 사용하지 않고 각 컨트롤에 저장된 상태 값(viewstate)을 이용해서 페이지를 구성할 수 있는데, http POST 정보에 있는 _VIEWSTATE 값을 디코딩해서 페이지에 포함된 서버 컨트롤

    의 값을 초기화 하게 되는 것이다. ('_VIEWSTATE'라는 이름의 hidden 요소가 자동 추가되는데 여기의 값은 암호문 처럼 알아 볼 수 없는 값으로 가득차 있다.)

    3. 위의 이벤트를 직접 Control를 활용하는 예제로 확인해 보겠다.
    웹 폼(control_event.aspx)을 추가하고 TextBox, CheckBox, Button Control을 추가 한다. 각각 Control의 속성창내 이벤트 영역에서 TextBox는 TextChanged, CheckBox는 CheckedChanged, Button는 Click 이벤트를 설정하고, CheckBox 2개중 1개에는 체크시 라운드트립이 발생하도록 AutoPostBack을 True로 설정하자. 설정완료한 Html Source이다.

    <%@ Page language="c#" Codebehind="control_event.aspx.cs" AutoEventWireup="false" Inherits="WebTest.control_event" %>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >

    <HTML>
        <HEAD>
            <title>control_event</title>
            <meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
            <meta name="CODE_LANGUAGE" Content="C#">
            <meta name="vs_defaultClientScript" content="JavaScript">
            <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
        </HEAD>

        <body ms_positioning="GridLayout">
            <form id="Form1" method="post" runat="server">
                <asp:TextBox id="TextBox1" runat="server" style="Z-INDEX: 103; LEFT: 16px; POSITION: absolute; TOP: 216px"></asp:TextBox>
                <asp:CheckBox id="CheckBox1" style="Z-INDEX: 101; LEFT: 16px; POSITION: absolute; TOP: 256px" runat="server"></asp:CheckBox>
                <asp:CheckBox id="CheckBox2" style="Z-INDEX: 104; LEFT: 136px; POSITION: absolute; TOP: 256px" runat="server" AutoPostBack="True"></asp:CheckBox>
                <asp:Button id="Button1" style="Z-INDEX: 102; LEFT: 16px; POSITION: absolute; TOP: 288px" runat="server" Text="Button"></asp:Button>
            </form>
        </body>

    </HTML>

(소스)Hellow.aspx

    각 Control별 설정한 이벤트 메소드 안에 기능을 추가하여 이벤트가 발생하였음을 확인해 보도록 하자.

    using System;
    using System.Collections;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Web;
    using System.Web.SessionState;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.HtmlControls;

    namespace WebTest
    {
        /// <summary>
        /// ASP.Net 페이지의 프로세싱이 Page_Init → Page_Load → PageUpLoad 단계로 이루어짐
        /// </summary>
        public class control_event : System.Web.UI.Page
        {
            protected System.Web.UI.WebControls.TextBox TextBox1;
            protected System.Web.UI.WebControls.CheckBox CheckBox1;
            protected System.Web.UI.WebControls.CheckBox CheckBox2;
            protected System.Web.UI.WebControls.Button Button1;         

            private void Page_Load(object sender, System.EventArgs e)
            {
                // 여기에 사용자 코드를 배치하여 페이지를 초기화합니다.
            }

            #region Web Form 디자이너에서 생성한 코드

            override protected void OnInit(EventArgs e)
            {
                // CODEGEN: 이 호출은 ASP.NET Web Form 디자이너에 필요합니다.
                InitializeComponent();
                base.OnInit(e);
            }               

            /// <summary>
            디자이너 지원에 필요한 메서드입니다.
            이 메서드의 내용을 코드 편집기로 수정하지 마십시오.
            /// </summary>

            private void InitializeComponent()
            {    
                this.CheckBox1.CheckedChanged += new System.EventHandler(this.CheckBox1_CheckedChanged);
                this.Button1.Click += new System.EventHandler(this.Button1_Click);
                this.TextBox1.TextChanged += new System.EventHandler(this.TextBox1_TextChanged);
                this.CheckBox2.CheckedChanged += new System.EventHandler(this.CheckBox2_CheckedChanged);
                this.Load += new System.EventHandler(this.Page_Load);
            }

            #endregion

            /// <summary>
            /// 이벤트 발생
            /// </summary>
            /// <param name="sender">이벤트를 발생시킨 객체(object)</param>
            /// <param name="e">이벤트의 정보를 가지는 이벤트 객체(arguments)</param>

            private void TextBox1_TextChanged(object sender, System.EventArgs e)
            {
                Response.Write ("TextBox1 컨트롤 : TextChanged 이벤트 발생<br>");
            }

            /// <summary>
            기본적으로 Button 계열의 컨트롤의 Click 이벤트만 즉시 PostBack 하도록 설정되어 있다. 그 외의 이벤트들을 페이지의 Post시에 일괄적으로 발생하고 처리된다. 하지만 경우에 따라서는 Button 이외의 컨트롤에서도 이벤트가 발생했을 때 즉시 PostBack 되도록 할 필요가 있는데 이때 사용하는 것이 "AutoPostBack" 프로퍼티이다. → ASP에선 OnClick Event를 Catch하여 Submit 시키는 방법을 사용한다.
            /// </summary>

            private void CheckBox1_CheckedChanged(object sender, System.EventArgs e)
            { 
                Response.Write("CheckBox1 컨트롤 : CheckedChanged 이벤트 발생<br>"); 
            }
            private void Button1_Click(object sender, System.EventArgs e)
            { 
                Response.Write("Button1 컨트롤 : Click 이벤트 발생<br>"); 
            }

            /// <summary>
            CheckBox2의 속성 창에서 "AutoPostBack"이라는 프로퍼티를 "True"로 설정하여, 체크/언체크시에 즉시 PostBack이 이루어 지도록 할 수 있다. AutoPostBack 프로퍼티는 기본적으로 'false'로 설정되어 있다. 이것은 불필요한 PostBack으로 인한 서버나 네트워크 부하를 줄이기 위함이다. 하지만 티켓예매시스템 같은 곳에서는 프로퍼티를 유용하게 사용할 수 있을 것이다.
            /// </summary>

            private void CheckBox2_CheckedChanged(object sender, System.EventArgs e)
            {
                Response.Write("CheckBox2 컨트롤 : CheckedChanged 이벤트 발생<br>");
            }
        }
    }

(소스)Hellow.aspx.cs 

    4. 웹 폼은 일반 컴포넌트 객체와 비슷한 수명주기를 가지는데 추가적으로 '렌더링'이라는 과정을 가진다.
   이러한 렌더링 과정을 이해하기 위한 핵심 용어가 바로 컨트롤 트리(control tree)이다.

    Page_Init 단계에서 페이지 내부의 컨트롤들에 대해서 계층적인 구조를 생성한다고 했었는데 이것이 바로 컨트롤 트리이다. Page는 이러한 트리 구조에서 유일한 루트가 된다. 이 루트는 시작점으로 해서 하나의 페이지는 컬렉션 기반의 계층구조로 구성이 된다. 그리고 모든 처리가 끝난 뒤에는 구성된 컨트롤 트리의 순서에 따라 차례대로 클라이언트로 보내어질 HTML로 렌더링되는 것이다. ASP.NET의 @page 지시어(Directive)에는 이러한 컨트롤 트리를 간단히 확인 할 수 있게끔 'Trace'라는 속성을 제공한다. 이러한 지시어에는 @page외에 @Register, @Assembley등이 존재한다.

<%@ Page language="c#" Trace="True" TraceMode="SortByCategory" %> 
    <html>
      <body>            
        <form runat="server">
            이름을 입력하세요 :  <asp:TextBox Runat=server />
        </form>         
      </body>
    </html>

    상기 소스를 실행하면 보고서 형식으로 해당 페이지에 관련된 여러 정보가 출력되는 것을 확인 할 수 있을 것이다.