관리 메뉴

새로운 시작, GuyV's lIfe sTyle.

닷넷 게시판 만들기 Part 15 - 서버컨트롤과 이벤트 본문

ⓟrogramming/asp.net 게시판

닷넷 게시판 만들기 Part 15 - 서버컨트롤과 이벤트

가이브 2011.01.31 18:11

2011/01/19 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 10
2011/01/20 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 11
2011/01/21 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 12
2011/01/25 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 13
2011/01/26 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 14

1. 닷넷 개발환경 준비, 테스트
2. 닷넷 알아보기 [7/7]
3. asp.net 컨트롤 [6/..]

이전 시간에는 asp.net 의 컨트롤 종류 중 하나인 HtmlForm 에 대해 간단하게 알아보았다.
HtmlForm 의 특징은 기존의 태그에서 runat=server 만 붙여주면 닷넷에서 제어가 가능한 컨트롤로 변하게 된다. 컨트롤의 고유값인 id 를 붙여주면 id.Value 처럼 해당 컨트롤의 속성에 접근할 수 있게된다.

여기서 Question! 호기심이 많으셔서 해보신 분도 있으시겠지만, runat="server" 를 붙여 만든 서버컨트롤, 그러니까,

<input type="text" id="user_name" runat="server">

이 태그는 user_name.Value 로 값을 넣거나, 가져오는 것이 가능하게된다.
그렇다면 서버컨트롤이 아닌 값을 받는 방식처럼 값이 submit 으로 넘겨졌을 때, user_name.Value로 읽을 수 있으면서, Request["user_name"] 으로도 값이 읽어질까?

모든 웹 프로그래밍의 결과물도 그렇지만,
서버컨트롤이 처리된 결과도 확인해봤었다. HTML. 그래봐야 HTML이다.
그러므로 Request["태그name"] 형식으로도 가능하다. 말하고 싶은 요지는 그것이다. 결과물은 꺽쇠인 <tag>다.

일반적으로 HtmlForm은 잘 쓰지 않는다. 이유는 (우리가 중점으로 다룰) WebForm 이라는 부류의 "더 닷넷스러운" 서버컨트롤들이 따로 존재하기 때문이다. 필자가 HtmlForm 을 먼저 제시하고 간을 본 이유는, 그저 닷넷의 결과물이 태그임을 강조하고 싶었기 때문이다.

조금 정리를 해보자.
<form>..</form>태그, 그러니까 HTML에서 입력받는 컨트롤의 종류를 모두 나열해보자.

<input type="..."> 의 형식의 입력폼
text : 자유롭게 입력하는 한 줄 입력
password : 비밀번호 입력 용도의(입력이 가려지는) 한줄 입력
hidden화면에 보여지지 않고 값을 저장하는 값
file 
: [찾아보기]와 같은 버튼을 눌러 컴퓨터에 있는 파일을 선택하여 전송할 수 있는 용도
radio : 여러개 중 하나만 고를 수 있는 동그란 체크 입력
checkbox : 여러개 중 하나 이상 여러개 고를 수 있는 네모 체크 입력
submit : <form>의 내용을 페이지로 전송하는 버튼
image : <form>의 내용을 페이지로 전송하는 이미지 버튼
reset : <form>의 변경된 내용을 모두 초기화 하는 버튼

<input> 태그가 아닌 다른 폼
textarea
: 엔터로 여러 줄의 내용을 넣을 수 있는 여러줄 입력.
select : 여러개 중 하나를 선택할 수 있는 형식의 입력
button : 누를 수 있는 버튼

혹시 이 태그를 아직 사용해보지 않았다면 직접 연습해서, 그 값들이 어떻게 넘어오는지 Request[""]로 받아서 값을 출력해보자. 예로, checkbox 같은 경우는 항목이 여러개 되지만, name은 한 개이다. 그렇다면 그 값은 Request[""]로 받았을 때, 여러개의 값은 어떻게 넘어오게 될까? radio 태그 역시, 여러개의 항목이지만 한 개만 고를 수 있기 때문에 그것들은 묶어져야 할 것이다.

우리가 알아볼 서버컨트롤인 WebForm은 위에 나열한 모든 것들이 다 포함되어 있다.
그 외에도 <form>태그용도가 아닌 일반적인 용도로 사용하는 태그들도 서버컨트롤로 제공된다.

서버컨트롤을 사용하는 목적은 태그를 프로그래밍 방식으로 접근하기 위해서이다.
프로그래밍 방식이라는 것은, 우리가 이 때까지 했던 클래스를 찾아서 해당 클래스의 메서드를 호출하거나 프로퍼티 값을 지정하거나 읽어오는 등의 방식이다.

이전 시간에 했었던 태그를 HtmlFrom 서버컨트롤로 만드는 과정을 다시 생각해보자.
태그에 runat="server" 를 붙이게 되면 해당 태그가 서버컨트롤이 되었다. 
이 말은, 해당 태그는 닷넷에서 제어가 가능하게 되었다는 말인데, 그 이유가 클래스로 변경되었기 때문이다. (그리고 클래스는 자동적으로 인스턴스 화가 된다) 그래서 우리는 클래스를 사용하듯이 값을 읽어오거나 넣는 id.Value 와 같이 해당 서버컨트롤 클래스가 제공하는 프로퍼티를 이용할 수 있게되는 것이다. 이것이 프로그래밍 방식으로 접근할 수 있게 되었다고 할 수 있다. 

닷넷은 클래스로 HTML 태그를 표현할 수 있다는 말인데 그렇다면 꺽쇠 형식의 태그문을 하드 코딩하지 않고(손수 키보드로 치지 않고) 클래스로만 만들어낼 수 있다는 말인가?

조금 과장을 섞는다면 그렇다. 섞은 과장은 "<html><body>" 같은 것들은 서버컨트롤로 제공을 하지 않기 때문이다. ^^ 하지만 "그렇다"라고 할 수 있는 이유는, 이들을 모두 프로그래밍 방식으로 접근을 가능할 수 있도록 "runat=server"만 붙여주면 되기 때문이다.

태그에 "runat=sever"를 붙여주는 것들을 HtmlForm 서버컨트롤이라고 했다. 서버컨트롤은 클래스라고 했다. 

http://msdn.microsoft.com/ko-kr/library/tct4wcsd(v=VS.80).aspx

이 MSDN 문서는 태그에 runat="server" 를 붙이면 각각의 태그 이름에 따라 바뀌는 클래스 목록이다. 클릭해서 우측 클래스의 이름, 설명을 대충 읽어보자.

읽어보니 어떤가? <a>, <button> 부터 시작해서, <head>태그도 있고, 심지어 <input type="reset"> 형식까지 존재한다. 그리고 여러분들이 사용해본 적이 없는 태그도 볼 수 있을 것이다. 물론, 100% 모든 HTML 태그가 다 지원되는 것은 아니다. 지원하지 않는 태그는 모두 특정한 형식으로 자동으로 바뀌게 되는데, HtmlGenericControl 이라는 클래스이다.

#참고
우리는 이 클래스들을 외울 필요가 없다. 지금 3장의 첫 Part 에서 여러분들을 암기의 노예로 만들지 않겠다는 필자의 말을 믿어주기 바란다.

이제 서버컨트롤을 눈으로 확인해보도록 하자.
앞서 말한적이 있지만, 클래스를 출력(Response.Write 등으로)하면 해당 클래스의 원형이 출력되게 된다. 클래스가 네임스페이스에 속해있으면 네임스페이스명까지 모두 출력한다.

<html>
<head>
      <title></title>
<head>
<body>
</body>
</html>

HTML에서 기본적으로 들어가야 된다고 말할 수 있는 태그이다.
html, head, title, body 이렇게 4개이다. (여기서 title 태그는 head 에 속해있다)
이 녀석들을 모두 서버컨트롤로 만들어보자.
만드는 방법은? 모른척 하지 마시라! 태그에 runat="server" 만 붙여주면 되지 않는가? 그리고 해당 태그에 접근하여 조작이 용이하도록 id 도 붙여주자.
그리고 이 4개의 id 를 그대로 Response.Write() 메서드로 화면에 출력해보도록 하자.

control2.aspx

<%@ Page Language="C#" runat="server" %>

<script language="C#" runat="server">

 void Page_Load()
 {
    Response.Write("html : " + HTML_TAG + "<hr>");
    Response.Write("head : " + HEAD_TAG + "<hr>");
    Response.Write("title : " + TITLE_TAG + "<hr>");
    Response.Write("body : " + BODY_TAG + "<hr>");
 }

</script>


<html id="HTML_TAG" runat="server">
<head id="HEAD_TAG" runat="server">
    <title id="TITLE_TAG" runat="server"></title>
</head>

<body id="BODY_TAG" runat="server">
</body>

</html>


진하게 표시된 4개의 기본태그에 id, runat="server" 를 붙여 서버컨트롤로 만들었다.
그리고 aspx 파일 실행시 자동으로 실행되는 Page_Load() 메서드에 4개의 id를 그대로 출력하는 소스이다. 우리 초보는 초보답게 Ctrl+C, Ctrl+V 를 사용하지 말도록 하자. (필자도 직접 다 타이핑한 것이다! ^^)

여튼, 실행 결과를 직접 확인해보자.



해당 태그의 id 를 그대로 출력해본 결과, 앞서 말한대로 해당 클래스가 System.Web.UI.HtmlControls.[서버컨트롤명] 형식으로 네임스페이스와 함께 출력된다. 클래스는 언제나 마지막 점(.) 다음에 나온다는 것을 여러분들인 MSDN에서 익히 봤기 때문에 알고 있을것이다. 이렇듯 서버컨트롤들을 한번씩 찍어보고 어떤 형식인지 확인하는 버릇을 들이는 것이 좋다.

이 것들은 앞서 MSDN에서 본 HtmlForm 관련 클래스에 모두 다 있는 것들이다.
<html>,<body>는 특정 서버컨트롤(클래스)로 딱히 제공되지 않기 때문에 HtmlGenericControl 이라는 일반 컨트롤로 변경되는 것을 알 수 있다.

이 컨트롤들은 모두 System.Web.UI 네임스페이스에 속해있다. aspx 파일에서 기본적으로 참조하는 네임스페이스이다. (그래서 참조하지 않아도 사용가능하다)
그중에 가장 보스(boss!)를 맡고 있는 클래스가 있다. 이번 3장의 내용이 '컨트롤'이지 않은가?

System.Web.UI.Control 클래스이다.
http://msdn.microsoft.com/ko-kr/library/system.web.ui.control(v=VS.80).aspx

보스라는 말 답게, 여러분들이 이 녀석을 쥐고 흔들 줄 안다면 asp.net 의 컨트롤은 100% 끝났다고 보면 된다. ^^ (필자는 사이좋게 손만 잡아봤을 뿐이다)

가장 중요한건 Control 클래스의 멤버이다. 여러분들이 앞으로 사용하는 모든 서버컨트롤이라는 클래스는 이 멤버를 사용할 수 있다. 그러니까, 수많은 서버컨트롤의 공통적인 속성이 여기 멤버에 속해있다는 말이다. 이 많은 것들이 앞으로 여러분들의 MSDN 라이프에 방해가 될 수 있을 것이다. 각각의 서버컨트롤의 멤버에 이 것들이 다 붙어있기 때문이다.

초보에게 함정이라고 말할 수 있다.
지긋지긋하게 많은 것들이 "상속관계"라는 이유로 싹 다 붙어서 헷갈리게 만드는 것이다.
그래서 필자의 말이 일리가 있다. 암기의 노예가 되지말자. 차라리 다음 항목들을 외워두자.

1. 사용하고 싶은 서버컨트롤(클래스)를 MSDN 검색으로 찾는다.
2. 무조건 "클래스 멤버"를 열어본다. 모든 것들이 다 나와있다.
3. 클릭하면 해당 메서드/프로퍼티 사용법의 예제와 설명이 다 나와있다. 그대로 쓰자.

(뭐..; 당연한 말이다.)


다시 control2.aspx 소스로 돌아오자.
서버컨트롤을 이용하는 이유라고 말했던 "프로그래밍 방식"으로 접근해보자.


다음 내용부터는 모든 서버컨트롤의 공통적인 것들이므로 매우 중요하다고 볼 수 있다. 꼭 마스터하도록 하자.

[ HTML Quiz ]
1. HTML 페이지에서 페이지의 배경을 바꾸기 위해서 <body> 태그에 어떤 속성을 어떻게 넣어야하나? bgcolor="색상영문명" 또는 bgcolor="#123ABC" 와 같은 16진수 RGB값  

2. HTML 페이지에서 한칸(스페이스,space)을 띄우는 특수문자는? &nbsp; 



이 정도로 하기로 하고, 1번 퀴즈문제처럼 controls2.aspx 파일의 배경을 바꾸어보자.

<body id="BODY_TAG" runat="server"> 이것을
<body id="BODY_TAG" runat="server" bgcolor="yellow">

추가해서 실행해보면 노란색으로 변경된다. 그러나 이건 하드코딩이지, 프로그래밍 방식이 아니다.

태그는 속성이라는 것으로 해당 태그에 옵션을 준다. 글꼴의 색을 바꿔라, 글꼴의 폰트를 바꿔라, 지금처럼 전체 html 색상을 노란색으로 바꿔라는 등, 속성이 대부분 이런 기능을 하기 위해 존재한다.

asp.net 의 모든 컨트롤에는 속성을 제어하기 위한 컬렉션(Collection)이 존재한다. 바로 Attributes 이라는 것인데, 이름처럼 속성(들)이라는 의미이다.

이 클래스는 AttributeCollection 을 말하는 것인데, 컬렉션은 대부분 클래스 뒤에 Collection을 지우고 s를 붙여서 표현한다. 컬렉션이란 간단하게 같은 클래스의 묶음이라고 생각하자.

사용하는 법은 간단하다. 

BODY_TAG 가 body 태그의 서버컨트롤이니,

BODY_TAG.Attributes 형식으로 이용하고, Attributes 는 컬렉션이니 배열의 형태로 접근가능하다.

(AttributeCollection 에도 명시되어 있지만) 
컬렉션이라는 형식에서 모두 사용할 수 있는 대표적인 메서드와 속성을 알아보자.

[메서드]
Add(string key, string value) : key라는 이름으로 value 값으로 추가
Clear() : 모두 삭제
Remove(string key) : 해당 key이름의 컬렉션 삭제

[속성]
Count : 해당 컬렉션의 갯수
Item : 컬렉션의 특성 값


이정도면 될 것 같다. 
이제 BODY_TAG 에 Attributes 라는 컬렉션으로, bgcolor 속성에 "yellow"라는 값을 넣어보자.
필자의 생각으로는 Add() 메서드로 가능할 것 같으며, key, value 형식대로 넣어보자.

controls2.aspx

<%@ Page Language="C#" runat="server" %>

<script language="C#" runat="server">

 void Page_Load()
 {
   Response.Write("html : " + HTML_TAG + "<hr>");
   Response.Write("head : " + HEAD_TAG + "<hr>");
   Response.Write("title : " + TITLE_TAG + "<hr>");
   Response.Write("body : " + BODY_TAG + "<hr>");

  BODY_TAG.Attributes.Add("bgcolor", "yellow");

 }

</script>


<html id="HTML_TAG" runat="server">
<head id="HEAD_TAG" runat="server">
 <title id="TITLE_TAG" runat="server"></title>
</head>

<body id="BODY_TAG" runat="server">
</body>

</html>



기존의 control2.aspx 소스에 파란색 소스만 추가된 것이다. 실행해보자. 그리고 실행 결과를 소스 보기로 확인해보자.



복잡해 보이지만, 확인해야 될 것은 body 태그에 bgcolor="yellow" 값이 붙어있다는 것이다.
이렇듯 서버컨트롤(태그)에 속성을 부여하는 것은 이런 방식으로 하면 된다.

이번에는 좀 더 복잡한 것을 해보자.
먼저, 텍스트박스와 버튼이 있고, 텍스트에 입력하고 버튼을 누르면 "Hello? <내용>"이 출력되는 것을 서버컨트롤로 추가, 실행까지 할 수 있게 구성해보자.

필요한 컨트롤은 submit 버튼이 들어가므로 <form>태그도 필요하겠다.
물론, 하드코딩으로 가능하지만, 지금은 프로그래밍 방식으로만 하고 있음을 생각하자. ^^

프로그램의 플로우차트(순서도)를 글로 표현해보자.

[컨트롤 생성, 추가]
1. <form>을 만들기 위해 HtmlForm 클래스를 사용한다.
2. <form> 에 '텍스트박스'와 '버튼'을 하나 넣는다.
3. 텍스트박스의 id 는 user_name(ID="user_name") 으로 준다.
4. 버튼에 나오는 텍스트는 "인사하기"라고 준다. (Value="인사하기")
5. 버튼을 클릭시 메서드를 호출하기 위해 이벤트(button_click)를 걸어준다. (이벤트? 처음보는 내용)
6. 그리고 출력을 위해 HtmlGenericControl 서버컨트롤을 추가한다.(ID="output")
7. <body>태그에 서버컨트롤 form을 추가한다. 
8. 추가된 form에 텍스트박스, 버튼 순으로 넣어준다.

[버튼클릭시 처리]
9. 버튼이 클릭됐을 때 호출되는 이벤트 메서드(button_click)를 만든다.
10. 출력되는 컨트롤인 output 을 FindControl("id명") 메서드로 찾아준다.
11. 텍스트박스 컨트롤인 user_name 을 FindControl("id명") 메서드로 찾아준다.
12. 텍스트박스에 값이 없으면 빨간색으로 output 에 "이름을 입력하세요!"라고 출력한다. 
13. 텍스트박스에 값이 있으면 "Hello! (입력값)" 의 형식으로 output 에 출력해준다


서버컨트롤을 프로그래밍 방식으로 추가하기 위해서는 클래스를 직접 사용하기 위해 해당 서버컨트롤의 클래스를 인스턴스 화를 해야한다. 예전에 다룬 적이 있었지만 한번 더 알아보자.
클래스를 땡겨쓰는 방법(인스턴스 화하는 방법)은 다음과 같다.

클래스명 사용할_이름 = new 클래스명();

클래스라는 것에는 꼭 "생성자"(Constructor)라는 것이 존재한다. 그 생성자가 없을때는 괄호를 그냥 열고 닫으면 된다. 서버컨트롤 대부분은 생성자가 없이도 가능하다.

< HtmlForm 서버컨트롤 클래스 목록 >
http://msdn.microsoft.com/ko-kr/library/tct4wcsd(v=VS.80).aspx 

목록에서 찾을 수 있듯이,
우리가 입력에 필요한 서버컨트롤이다. 

우리가 프로그래밍 코드를 이용해 구조적으로 생성하려는 모습은 다음과 같을 것이다.

<form runat="server">
       <input type="text" id="user_name" runat="server">
       <input type="submit" runat="server" value="인사하기">
</form>
<span id="output" runat="server">(력할 메시지용도)</span>



태그로 따져보면 위와 같다. 다음은 해당 태그의 서버컨트롤이다. (필자처럼 직접 찾아보기 바란다)

<form>..</form> 태그의 서버컨트롤은 HtmlForm 클래스이다.
<input type="text"> 태그인 텍스트박스 서버컨트롤의 클래스는 HtmlInputText 이다. 
<input type="submit"> 태그인 페이지를 전송하는 서버컨트롤의 클래스는 HtmlInputSubmit 이다. 

출력은, 간단하게 텍스트로 할 예정이니, <span>을 사용하자. 이 태그는 기본적으로 HtmlGenericControl 을 사용하면 된다.

이렇게 만든 것들은 모두 <body>에 넣으면 된다.
단, 텍스트박스와 submit 버튼은 <form>에 넣어야 되겠다.

컨트롤을 넣는 방법은 간단하다.

body 의 id 값이 BODY_TAG 이니,
BODY_TAG.Controls.Add(컨트롤 인스턴스명);

이렇게, ControlCollection 으로 넣으면 된다.

예제로, 텍스트박스 하나를 <body>에 넣어보자.

void Page_Load()
{

H
tmlInputText textbox = new HtmlInputText();   // 인스턴스 화
textbox.ID = "user_name";                 // 구분할 수 있게 ID 부여
textbox.Size = 20;                         // Size 속성을 20으로 줌.
  BODY_TAG.Controls.Add(textbox);

}


이 정도면  직접 MSDN에서 해당 클래스를 찾아서 완성시킬 수 있을 것이다.

문제는 버튼을 클릭 이벤트 연결인데, 우리가 예전에 태그로 서버컨트롤을 지정하여 사용했을 때에는 다음처럼,

<input type="submit" runat="server" onserverclick="button_click">

onserverclick 속성을 지정하면 되었다. 그리고 button_click(object, EventArgs) 메서드를 만들어주면 사용가능했었다.

코드상에서 이벤트를 연결하는 방식은 일반적으로 다음과 같다.

클래스명.이벤트명 += new EventHandler(메서드명);

이벤트명은 해당 클래스의 MSDN에서 찾을 수 있다.HtmlInputSubmit 클래스멤버에서 ServerClick 이벤트를 찾아보자. 번개모양의 아이콘이 이벤트이다. 예제도 있으니 참고하자.
그리고 여기서 += 표시인 연산자는,

a += 1;           // a = a + 1;
b -= 1;           // b = b - 1;

형식으로 사용하는 것으로 알고 있는데, 이벤트를 지정시 +=, 이벤트 해제시 -= 를 사용한다고 생각하자. 

우리가 만들 버튼의 이벤트를 예를 들어 소스를 만들어보자.

 void Page_Load()
 {

  HtmlInputSubmit button = new HtmlInputSubmit();
  button.Value = "인사하기";
  button.ServerClick += new EventHandler(button_click);
 }

void button_click(object o, EventArgs e)



이런 규칙만 알아놓으면 어떤 컨트롤도 별 다를 것 없이 사용할 수 있게 된다.
이벤트명은 해당 클래스마다 제공하는 이름이 다르니 MSDN을 참고해야 한다.

지금 이렇게 컨트롤 몇개 추가하는 것도 복잡해 보일 수 있지만, 프로그래밍 방식을 이용해서 컨트롤을 페이지에 붙이는 것은 드물다고 보면 된다. 이 예제를 하는 이유는, 서버컨트롤의 역할을 좀 더 자세하게 알아보기 위해서이다. 

완성은 여러분들이 직접 다음에 링크된 소스를 열기전에 해봤으면 한다.
단, 실행 후 꼭 "소스보기"로 태그가 어떻게 랜더링 되었는지(서버컨트롤이 어떻게 태그로 변환되었는지) 확인하자.

control2.aspx


프로그래밍 방식으로 컨트롤을 생성하는 것을 "동적 컨트롤 생성"이라고 한다.
이 값들은 프로그램에서 특정 값에 따라 얼마든지 변경될 수 있기 때문이다.

예를 들면, 실제 시간에 맞추어서 "아침:하얀색 / 점심:노란색 / 저녁:검은색"으로 홈페이지의 배경을 바꿀 수도 있을 것이다. 그리고 글자 크기를 그때그때 다르게 할 수도 있을 것이다.

이번 시간에는 태그를 프로그래밍적으로 변경하는 "닷넷스러움"을 맛보았다.
여러분들이 알고 있는 태그들이 지금 머리에서 서버컨트롤로 변경되고 있지는 않은가?

아마도 태그를 많이 보셨다면 <table>..</table> 태그를 알고 있을 것이다.

  <table>               (HtmlTable)
   <tr>                   (HtmlTableRow)
       <td>              (HtmlTableCell)
            내용
       </td>
  </tr>
</table>

테이블은 table -> tr -> td 구조를 가지고 있다.
해당 서버컨트롤은 모두 MSDN에 역시 다 나와있으니 참고하기 바란다.

이 테이블을 이용해 서버컨트롤로 만든 예제이다.


control3.aspx



HTML 태그를 알면 asp.net 을 이해하기 쉽다는 말을했었다.
아마 지금은 느끼시리라 믿는다.


다음시간에..


0 Comments
댓글쓰기 폼