티스토리 뷰
C#.NET에서 다양한 사용자 컨트롤을 만들어 놓고 윈도우 폼에 적용해서 사용하는 경우 윈도우 폼 클래스에서 개별 컨트롤의 임의의 속성을 참조하거나 메소드를 실행시킬 필요가 있을 때가 있습니다.
닷넷에서는 System.Reflection을 통해서 프로그램 실행 중에 특정 클래스의 속성이나 메소드를 찾아서 참조하거나 호출할 수 있도록 기능을 제공하고 있습니다. 마치 자바 스크립트와 같은 웹 스크립트 언어에서 지원하는 기능을 사용할 수 있습니다.
윈도우 폼에 도구 상자에 있는 다양한 컨트롤이나 사용자 컨트롤을 배치하면 위의 그림과 같이 Form>Panel>Control과 같은 계층 구조를 갖게 됩니다. Form 오브젝트의 .Controls를 확인하면 Form에 속한 두개의 판넬 오브 젝트를 찾을 수 있고 각 Panel 오브젝트의 .Controls를 확인하면 판넬에 속한 사용자 컨트롤을 확인할 수 있는 원리입니다. 이러한 원리를 기반으로 상위 오브젝트의 .Controls부터 차례대로 확인하다보면 개별 사용자 컨트롤을 만날 수 있는데 현재 오브젝트가 버튼이나 텍스트박스와 같은 특정한 컨트롤인지는 다음과 같이 확인할 수 있습니다.
foreach (Control control in this.Controls) { if (control.GetType() == typeof(Button)) { //blah blah } }
개별 컨트롤의 GetType() 메소드를 통해서 오브젝트의 클래스 정보를 확인할 수 있습니다. 주의할 점은 위에서 언급한 것과 같이 상위 오브젝트의 .Controls에는 바로 아래 단계의 오브젝트 정보만을 가지고 있기 때문에 모든 오브젝트를 확인하고 싶다면 회귀적인(Recursive) 함수를 제작해서 확인해야만 합니다.
public void setControl(int idx, Control.ControlCollection cntls) { object[] objpara = { idx }; foreach (Control cobj in cntls) { if (cobj.GetType().GetProperty("TagId") != null) { string tagid = cobj.GetType().GetProperty("TagId").GetValue(cobj, null) as string; if (tagid.Length >= 6) { if (cobj.GetType().GetMethod("SetControl") != null) { cobj.GetType().GetMethod("SetControl").Invoke(cobj, objpara); } } } else if (cobj.Controls.Count > 0) { setControl(idx, cobj.Controls); //recursive search } } }
위의 함수는 Form에서 this.Controls를 인수로 호출하면 해당 폼에 속한 모든 컨트롤을 뒤져서 "TagId"란 속성이 존재하고 해당 속성값의 길이가 6이상 일때 SetControl이란 메소드를 찾아서 전달된 인수값을 실어 호출하는 작업을 수행합니다.
GetType()으로 추출한 클래스 정보를 바탕으로 GetProperty("")를 호출하면 속성 정보를 추출할 수 있고 GetMethod("")를 호출하면 메소드 정보를 추출할 수 있습니다. 속성이나 메소드의 존재가 확인되면 속성은 GetValue()로 참조할 수 있고 메소드는 Invoke()로 호출할 수 있습니다. Invoke()로 메소드를 호출할 때는 첫 인수는 현재 오브젝트를 두번째 인수는 해당 메소드가 원래 받는 인수들을 배열로 전달하면 됩니다.
'프로그래밍' 카테고리의 다른 글
비주얼스튜디오용 콘솔 만들기 (0) | 2016.08.18 |
---|---|
C#에서 다중 모니터 사용하기 (0) | 2016.08.05 |
ASP.NET 웹 페이지 개발 맛보기 (0) | 2016.08.02 |
ASP.NET VB 레이저 문법 정리 (0) | 2016.06.15 |
ASP.NET C# 레이저(Razor) 문법 정리 (0) | 2016.06.14 |