Control.Name을 기준으로 하위 컨트롤 찾기 (재귀 사용)

동적 컨트롤 생성/수정/삭제

  코딩을 하다 보면 동적으로 컨트롤을 생성하고 수정하고 삭제해야 하는 일이 비일비재하게 일어납니다. 그런데, 생성하는 거야 뭐 순서대로 생성하면 된다 치지만 수정과 삭제는 어떻게 해야할까요?

  C#에서 모든 컨트롤은 Name 속성을 가지고 있습니다. Name 속성은 string 형식의 컨트롤의 고유 이름을 저장하는 식별자 역할을 하신다고 보시면 됩니다. 이 Name 속성을 사용해 동적으로 컨트롤을 생성할 때마다 Name을 할당해주면 나중에 수정/삭제시 이를 통해 특정 컨트롤을 손쉽게 찾아 작업할 수 있습니다.

  동적으로 컨트롤을 생성하고 Name을 할당하는 것을 보여드리죠.
private void CreateControls()
{
    var parent = tlpMain;
    
    for (int i = 0; i < 100; i++)
    {
        var chk = new CheckBox();
        chk.Checked = true;
        chk.Name = $"chk_{i}";

        var tb = new TextBox();
        tb.Name = $"tb_{i}";

        parent.Controls.Add(chk);
        parent.Controls.Add(tb);

        parent.RowCount++;

        parent.RowStyles.Add(rowStyle);
    }
}


  자, 위와 같이 코드를 작성하고 CreateControls 메소들를 호출하면 tlpMain이라는 테이블 레이아웃 패널에 각각 100개의 체크박스와 텍스트박스 페어가 자식 컨트롤로 등록됩니다. 그리고 각각의 체크박스와 텍스트박스는 "chk_#"과 "tb_#"이라는 Name 속성으로 식별되죠.

Name 속성을 사용해 하위 컨트롤 찾기

  근데 상황이 항상 이렇게 쉽게 쉽게 흘러가는 것은 아닙니다. 간단히 생각해 컨트롤 A의 하위에서 Name이 "B"인 B 컨트롤을 찾는다 정도의 상황이라면 foreach문을 사용해 A의 하위 컨트롤을 돌며 찾으면 되겠지만, 컨트롤 A의 하위 컨트롤과 그 컨트롤의 모든 하위 컨트롤에서 Name이 "B58"인 B 컨트롤을 찾는다" 씩이나 되는 상황이라면 얘기가 달라집니다.
  우선 A 컨트롤 하위에 A1컨트롤이 있고 A2, A3... A100이 있다고 칩시다.  A1컨트롤 하위엔 A11과 A12, A13... 그리고 그 하위에 B 컨트롤이 있고 B1, B2, B3... 이런 식으로 반복된다면 foreach 하나 가지고는 찾는 데 너무 엄청난 시간이 걸리죠.

  그렇다면 재귀 함수를 만들어 활용해봅시다.
public static Control GetChildControlByName(this Control ctrl, string name)
{
    foreach (Control c in ctrl.Controls)
    {
        if (c.Name == name)
            return c;
        else
            return c.GetChildControlByName(name);
    }
}


  부모 컨트롤의 모든 자식 컨트롤에 대해 Name이 인자와 같다면 해당 자식 컨트롤을 반환하고, 그렇지 않다면 다시 자식 컨트롤의 자식 컨트롤에서 찾기 시작합니다. 이렇게 첫 자식 컨트롤의 모든 자식 컨트롤에서 찾을 수 없었으면 다음 자식 컨트롤로 넘어갑니다. 재귀 함수를 이용한 하위 Name 속성을 이용해 하위 컨트롤을 찾는 방법입니다.

댓글

이 블로그의 인기 게시물

C# 남아도는 메모리에도 불구하고 OutOfMemoryException이 발생한다면?

USB를 뒤는 괜찮은데 앞에 꽂으면 인식이 힘들다?

MySQL 데이터 타입과 Java 데이터 타입 비교/매칭