asp.net2006. 9. 18. 22:38

ASP.NET 2.0에는 Master Page라는것이 새로 생겼다.  마스터 페이지의 개념을 MSDN에 나온 그대로 옮기면 다음과 같다.

"ASP.NET 마스터 페이지를 사용하면 응용 프로그램의 페이지에 대해 일관된 레이아웃을 만들 수 있습니다. 단일 마스터 페이지는 응용 프로그램의 모든 페이지 또는 페이지 그룹에 대해 원하는 모양과 느낌 및 표준 동작을 정의합니다. 그런 다음 표시할 콘텐츠가 포함된 개별 콘텐츠 페이지를 만들 수 있습니다. 사용자가 요청한 콘텐츠 페이지는 마스터 페이지와 병합되어 마스터 페이지의 레이아웃과 콘텐츠 페이지의 콘텐츠가 조합된 결과가 만들어집니다."

그런데, Master Page - Content Page가구성이되면, 마치 ASCX처럼 내부로 중첩된 컨트롤들의 Client ID가 아주복잡해지는 것을 소스보기에서 볼 수가있다. 이렇게..

<input name="ctl00$ContentPlaceHolder1$TextBox1" type="text" id="ctl00_ContentPlaceHolder1_TextBox1" />


그래서, 자바스크립트를 사용해서 제어하고자 할 때 반드시 서버사이드에서 그 컨트롤의 ClientID를 구해서 해야한다.다음은 Master Page에서 자바스크립트로 Content Page의 컨트롤을 제어하는 샘플이다.

마스터 페이지에는 버튼 컨트롤과 텍스트 박스 컨트롤을 하나씩 올려 두었다.

ASPX 소스는 아래처럼 된다.

<%@ Master Language="C#" AutoEventWireup="true" CodeFile="MasterPage.master.cs" Inherits="MasterPage" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
  <title>제목 없음</title>
</head>
<body> <form id="form1" runat="server">   
       <input id="Button1" type="button" value="button" onclick="return Button1_onclick()" />&nbsp;
       <input id="Hidden1" type="hidden" runat="server" /><br />
       <br />
       <asp:contentplaceholder id="ContentPlaceHolder1" runat="server">
           </asp:contentplaceholder>   
  </form>
</body></html>


컨텐트 페이지에는 텍스트박스 컨트롤을 하나 올렸다.


ASPX 소스는 아래처럼 구성된다.
<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="Default2.aspx.cs" Inherits="Default2" Title="Untitled Page" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
  <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</asp:Content>


목표는 마스터페이지에서 버튼을 눌렀을 때, 컨텐트 페이지의 텍스트 박스에 "aaa"라는 값이 들어가게 하는 것이고, 이를 자바스크립트를 사용해서 수행하는 것이다. 그 코드는 다음과 같다.

protected void Page_Load(object sender, EventArgs e)
{
     //contentPlaceHolder1은 Master페이지에 기본적으로 들어있는 PlaceHolder 컨트롤의 이름이다.
     //이 내부에 각 컨텐트 페이지의 컨트롤들이 들어있다.
     //즉 ContentPlaceHolder1.Controls 를 뒤지면 나온다는 얘기다.
     //그래서 루프를 돌면서 찾도록 한다.
     foreach (Control con in this.ContentPlaceHolder1.Controls)
     {
         //원하는 것을 찾기 위해서는 종류나 ID 같은 것을 알면 된다.
         if (con.GetType().Name == "TextBox" con.ID == "TextBox1")
         {
             //ClientID를 알 수 있다. 히든에다 넣는다.
             this.Hidden1.Value = con.ClientID;
         }
     }
     //자바스크립트를 생성한다.
     //렌더링된 자바 스크립트는 아래와 같은 모양이다.
     //        function Button1_onclick() {
     //        var conID = document.all.item("ctl00_Hidden1").value;
     //        eval("document.all.item('" + conID + "').value = 'aaa'");
     //        }
     //즉, 히든에 넣은 textbox 컨트롤의 ID를 구한 후,
     //eval문을 사용해서 컨트롤에 'aaa'라는 값을 넣는 스크립트를 실행하는 것이다.
     string scriptCode = "function Button1_onclick() {" + System.Environment.NewLine;
     scriptCode += " var conID = document.all.item(\"" + this.Hidden1.ClientID + "\").value;" + System.Environment.NewLine;
     scriptCode += "eval(\"document.all.item('\" + conID + \"').value = 'aaa'\");" + System.Environment.NewLine;
     scriptCode += "}";

     //페이지에 클라이언트 스크립트를 등록한다.
     this.Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Click", scriptCode, true);
}


주석에도 설명이 되어 있지만, 포인트는 마스터 페이지에 있는 PlaceHolder 컨트롤 내부에서 그 컨텐트 페이지에 있는 컨트롤을 찾는 것이다. 일단 찾은 후에는 그 ClientID 속성을 구할수 있으므로, 이 샘플보다 복잡한 스크립트도 얼마든지 수행시킬 수가 있다.
Posted by kkongchi