공룡호가 사는 세상 이야기

동적으로 생성된 컨트롤의 이벤트 처리시 넘기는 인자값으로 인한 문제입니다.

 

int NumSearch = 1

LOOP()

{

                        Button btnSearchUp = new Button();  // 버튼 객체 생성

                        btnSearchUp.Width = 70;

                        btnSearchUp.Text = "UpLoad";

                        btnSearchUp.ID = "btnSearchUp" + NumSearch.ToString();

                       

                        // 이 버튼의 명령인자에 파일의 경로와 파일 이름으로 설정

                        btnSearchUp.CommandArgument = temp;

 

                        // 해당 버튼에 이벤트를 걸어준다.

                        btnSearchUp.Click += new EventHandler(btnSearchUpClick);

 

                        NumSearch++;

}

 

 

이런 식으로 하여, 동적으로 컨트롤을 생성합니다.

컨트롤 아이디는 보시는 바와 같이 "btnSearchUp" + 1 ... 2 ... 3 이런식으로 컨트롤의 아이디가 붙습니다.

그리고 버튼의 CommandArgument 속성에 temp라는 string을 넣습니다. 그러면

아래쪽에 해당 버튼의 클릭 이벤트를 만들어 준 곳에서 이 CommandArgument 속성이 전달이 됩니다.

 

        void btnSearchUpClick(object sender, EventArgs e)

        {

             ((Button)FindControl("btn")).CommandArgument    

        }

 

이벤트 메서드 입니다.

이 부분은 엄준일 님께서 알려 주셨는데요. 이렇게 이벤트를 처리하는 메소드는 1개 뿐입니다.

전달 인자를 찾아 내기 위해서 위와 같은 방법을 쓴다는데, 이 부분은 버튼 컨트롤을 FindControl() 메서드로 찾아서 해당 속성을

추출하는 것 처럼 보입니다만, 저 부분의 "btn" 부분은 컨트롤의 아이디가 아닌가요?

컨트롤의 아이디로 알고 있는데, 여기서 문제가 생깁니다.

 

예를 들어, 위에서 동적으로 10개의 버튼 컨트롤을 생성했습니다.

그런데 사용자가 어떠한 버튼을 클릭할 지 알 수 없는데,

이벤트 처리 메서드에서는 어떻게 사용자가 클릭한 버튼 컨트롤의 아이디를 찾아서 해당 속성을 가져온다는 말인가요?

 

이러한 문제는 어떻게 해결해야 하나요?

 


 

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server">

    <title>제목 없음</title>

</head>

<body>

    <form id="form1" runat="server">

    <div>

               <input type="hidden" id="hid" name="hid" />

    </div>

    </form>

</body>

</html>

----------------------------------------------------------------------------

        protected void Page_Load(object sender, EventArgs e)

        {

               for (int i = 0; i < 10; i++)

               {

                       Button btn = new Button();

                       btn.ID = "btn" + i;

                       btn.Click += new EventHandler(btn_Click);

                       btn.Attributes["onclick"]     = "form1.hid.value = '" + "btn"+i + "';";

                       btn.Text = i.ToString();

                       btn.CommandArgument = "인자값 : " + i.ToString();

 

                       form1.Controls.Add(btn);

                       form1.Controls.Add(new LiteralControl("<br/>"));

               }

        }

 

        void btn_Click(object sender, EventArgs e)

        {

               string btnString       = Request["hid"].ToString();

 

               Response.Write( "버튼 컨트롤 아이디 : " + btnString + "<br>");

               Button btn = (Button)FindControl( btnString );

               Response.Write( btn.CommandArgument );

        }

---------------------------------------------------------------------------------------------

이 소스는 10 개의 버튼을 생성한 후에 버튼을 클릭하게 되면 html 히튼 컨트롤에 버튼의 아이디 값을 넣습니다.

 

그리고 포스트백 후에 버튼 이벤트가 실행되겠지요.

 

버튼 이벤트에서 버튼의 아이디 값을 가져옵니다. 그것으로 마져 CommandArgument 값을 가져오지요..

 

ASP나 JSP 식의 코딩이지요~

 

이전에도 말씀드렸다 시피, 닷넷의 생산성이 높다는 것의 하나가 바로 바인딩 가능한 서버 컨트롤이 있기 때문이지요.

 

똑같은 소소를 DataList 로 작성해 보면..

 

<%@ Import Namespace="System.Data" %>

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

 

<script runat="server">

        private void Page_Load(object sender, EventArgs e)

        {

               if( IsPostBack ) return;

              

               // 가상의 데이터

               DataTable dt = new DataTable();

               dt.Columns.Add("Title", typeof(string) );

 

               for (int i = 0; i < 10; i++)

               {

                       DataRow row = dt.NewRow();

                       row["Title"] = "btn"+i;

                       dt.Rows.Add( row );

               }

              

               dlList.DataSource      = dt;

               dlList.DataBind();

        }

 

        protected void dlList_ItemCommand(object source, DataListCommandEventArgs e)

        {

               if (e.CommandName == "upload")

               {

                       Response.Write( e.CommandArgument.ToString() + "버튼이 클릭되었습니다");

               }

        }

</script>

 

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server">

    <title>제목 없음</title>

</head>

<body>

    <form id="form1" runat="server">

    <div>

               <asp:DataList ID="dlList" runat="server" OnItemCommand="dlList_ItemCommand">

                       <ItemTemplate>

                              <%# DataBinder.Eval(Container.DataItem,"Title") %> <asp:Button ID="btn" runat="server" CommandName="upload" Text='Upload' CommandArgument='<%# DataBinder.Eval(Container.DataItem,"Title") %>'></asp:Button>

                       </ItemTemplate>

               </asp:DataList>

    </div>

    </form>

</body>

</html>

 

소스량은 언듯 비슷해 보이네요~

 

하지만 작성하면서 직관성이 매우 차이가 나고, 직관적이므로 디버깅도 용이해 지겠죠~

 

또한 후자처럼 작성하시게 되면 아시겠지만, 속도면에서도 굉장히 빨라집니다.

 

VS 2003 에서 작성하시는거라 위의 녹색 부분은 Oninit 메서드에서 이벤트로 따로 연결해 주셔야 합니다.

 

DataList 의 편리함을 뒤늦게라도 아시면... "아차~ 왜 진작 안썼지~" 라고 후회하실거에영^^;

'프로그래밍' 카테고리의 다른 글

공사  (0) 2007.04.17
매시업 데이터  (0) 2007.04.15
C#으로 openAPI 이용. 그리고 XML의 파싱  (0) 2007.04.04
WEB 2.0 관련자료  (0) 2007.03.27
DefiningSOA as an Architectural Style  (0) 2007.03.27