ASP.NET 2.0 Master Page의 컨트롤에서 자바스크립트로 Content Page의 컨트롤을 제어하기

2007. 1. 30. 09:24 IT 및 개발/ASP.NET & AJAX

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의 컨트롤을 제어하는 샘플이다.

마스터 페이지에는 버튼을 하나 올렸다.

사용자 삽입 이미지

<%@ 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>

컨텐트 페이지에는 텍스트 박스를 하나 올린다.

사용자 삽입 이미지

<%@ 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 속성을 구할 수 있으므로, 이 샘플보다 복잡한 스크립트도 얼마든지 수행시킬 수가 있다.

출처 : 게으른 개발자