[C#] 윈도우 컨트롤의 이벤트 메서드를 하나로.

2014. 10. 31. 19:30Coders

현업에서, 폼 개발을 할 때 디자인타임에 이벤트핸들러를 붙이면 좀 위험합니다. 디자인타임에 버튼 클릭 이벤트를 붙이려면 그냥 해당 버튼을 더블클릭하면 되죠. 그런데, 이 경우에, 만약 그 버튼을 Ctrl+X 등으로 잘라내어 다른 곳으로 붙이면, 해당 버튼에 바인딩 된 이벤트 핸들러의 연결고리가 끊기게 됩니다. 다른 모든 컨트롤들의 이벤트도 마찬가지 입니다. 이는, 컨트롤 이름을 자주 변경하거나 뭐 여기저기 갖다 붙이고 하게 되면 빈번히 발생하는 문제 중 하나 입니다.


실 예로, 예전 다니던 어떤 회사에서는 코딩 경력 10년이 넘는 친구 인데, 이러한 내용을 몰라 크게 실수한 적이 있습니다. 해당 문제로 인해 회사에서는 고객에게 적지않은 금액을 배상 해야 했고요.


난 뭐 이벤트 핸들러를 그냥 붙이는 게 좋아. 그게 내 규칙이야, 난 조심스러운 사람이니까... 하면 뭐 상관 없습니다. 하지만, 비주얼스튜디오는 인텔리센스가 잘 되어 있어 간단하게 코딩이 들어가는 Partial class 의 생성자 내에서 디자인 쪽의 메서드인 InitializeComponent(); 바로 밑에 다음과 같이 코딩하면(탭 키 몇 번 누르면) 메서드가 생성이 됩니다.



직장 후배들에게는 이에 대해(전 회사 경험을 포함해서) 항상 강조합니다. 남한테 강요하는 걸 좋아하지 않는 성격이라, "뭐 문제를 일으키지 않을 자신 있으면 맘대로 하든가." 라고 말꼬리를 붙이긴 하지만 말이죠.(좀 무책임한가요?)


그런데, 이렇게 버튼이 많으면....



컨트롤이 무지 많을 때엔 일일이 이벤트 핸들러를 붙이기가 귀찮아지기 때문에, 이런 방법을 사용하기도 합니다. 자세한 설명은 생략하고요, 대략적으로 이야기 하자면, 버튼 클릭 대리자 메서드를 하나만 만들어 두고, 해당 메서드에서 버튼 이름 등으로 어떤 버튼이 눌렸는지 분기를 태우는 방식 입니다. 그림을 보면 다음과 같습니다.


이렇게 해 놓고 띄워서 버튼을 클릭하면, 잘 작동함을 볼 수 있습니다.(이 이미지는 다 합성인 거 아시죠?)



그런데요, 이것도 귀찮습니다. 해당 폼의 자식들(Children) 중 버튼인 걸 찾아서 다 붙여주는 Static 유틸 메서드를 만들어서 사용할 수 있습니다.

이렇게요.


유틸 클래스의 소스 입니다.

namespace with.soju.tistory.com
{
	public class Util
	{
		//Recursive 하게 이벤트 붙여준다.
		public static void AddButtonEvents(Control parent, EventHandler buttonClickEvent)
		{
			if (parent.Controls.Count < 1)
				return;

			foreach (Control ctrl in parent.Controls)
			{
				if (ctrl is Button)
				{
					(ctrl as Button).Click -= buttonClickEvent;
					(ctrl as Button).Click += buttonClickEvent;
				}
				else
				{
					AddButtonEvents(ctrl, buttonClickEvent);
				}
			}
		}
	}
}


윈폼 소스입니다.

namespace with.soju.tistory.com
{
	public partial class Form1 : Form
	{
		public Form1()
		{
			InitializeComponent();

			Util.AddButtonEvents(this, this.Form1_Click);
		}

		private void Form1_Click(object sender, EventArgs e)
		{
			Button btn = sender as Button;

			MessageBox.Show(btn.Text);
		}
	}
}

귀찮음이 심하면, 이것저것 많이 해 보게 됩니다.