CheckBox와 RadioButton도 Button 컨트롤 만큼 자주 사용하는 컨트롤입니다. 두 개의 컨트롤은 모두 체크 상태를 속성으로 갖는 컨트롤입니다. 특히 RadioButton은 여러 개의 항목 중에 하나의 항목만 체크 상태를 갖을 수 있는 특징을 갖고 있습니다.
CheckBox와 RadioButton 컨트롤을 사용할 때 프로그램 방식으로 상태를 변경할 수도 있어야 하며 현재 체크 상태를 파악할 수 있어야 할 것입니다. 또한 사용자에 의해 체크 상태가 바뀌는 시점도 알 수 있어야 합니다.
이번에 실습에서 만들 프로젝트에는 자동차, 집의 소유 유무를 설정할 CheckBox 컨트롤과 성별과 혈액형을 설정할 수 있는 RadioButton으로 구성합니다. 두 개의 체크 박스를 클릭하여 체크 상태가 바뀌면 Label에 이들의 체크 상태를 표시합니다. 그리고 확인 버튼을 누르면 CheckBox와 RadioButton의 체크 상태에 따라 Label에 메시지를 표시합니다. 마지막으로 초기화 버튼을 누르면 초기 상태로 변합니다.
다음은 Form1의 자식 컨트롤 Name과 형식입니다.
No | Name | 컨트롤 형식 | 설명 |
1 | cb_car | CheckBox | 자동차 소유 |
2 | cb_house | CheckBox | 집 소유 |
3 | gbox_gender | GroupBox | 성별 그룹 박스 |
4 | rbtn_female | RadioButton | 여성 |
5 | rbtn_male | RadioButton | 남성 |
6 | gbox_blood | GroupBox | 혈액형 그룹 박스 |
7 | rbtn_o | RadioButton | O 형 |
8 | rbtn_a | RadioButton | A 형 |
9 | rbtn_b | RadioButton | B 형 |
10 | rbtn_ab | RadioButton | AB 형 |
11 | lb_msg | Label | 소유 상태를 실시간으로 알려주는 메시지 |
12 | btn_check | Button | 현재 상태 확인 |
13 | btn_init | Button | 전체 상태 초기화 |
14 | lb_own | Label | btn_check 클릭 시 소유 정보 나타냄 |
15 | lb_gender | Label | btn_check 클릭 시 성별 정보 나타냄 |
16 | lb_blood | Label | btn_check 클릭 시 혈액형 정보 나타냄 |
Form1 에서는 혈액형과 성별과 자동차, 집 소유 유무를 기억해야 합니다. 자동차와 집 처럼 CheckBox 일 때는 속성 Checked 를 확인하면 소유 유무를 판달할 수 있습니다. 하지만 RadioButton에서는 여러 개의 컨트롤 중에 하나만 Checked 상태여서 그룹에 있는 모든 컨트롤의 Checked 상태를 확인하는 것보다 멤버 필드로 기억하게 합시다.
public partial class Form1 : Form { enum Blood { NONE, BLOOD_O, BLOOD_A, BLOOD_B, BLOOD_AB } bool is_female; Blood blood; ...중략... }
이 프로그램은 Form1 개체를 Load 할 때와 초기화 버튼을 클릭하면 컨트롤들을 초기 상태로 변경합니다. 이를 위해 Load 이벤트 핸들러와 btn_init의 클릭 이벤트 핸들러를 추가하세요. 그리고 두 개의 이벤트 핸들러에서는 같은 작업을 수행할 것이므로 Init() 메서드를 별도로 정의하기로 합시다.
private void Form1_Load(object sender, EventArgs e) { Init(); } private void btn_init_Click(object sender, EventArgs e) { Init(); } private void Init() {
성별을 기억하는 is_female 변수는 true 로 설정하고 blood는 O형으로 설정합시다.
is_female = true; blood = Blood.BLOOD_O;
그리고 cb_car와 cb_house의 Checked 속성을 false로 설정합니다.
cb_car.Checked = cb_house.Checked = false;
rb_female과 rb_o의 Checked 속성은 true로 설정합니다.
rb_female.Checked = rb_o.Checked = true;
집이나 자동차는 사용자의 선택에 따라 실시간으로 소유 정보를 나타내기로 하였습니다. 초기화 작업에서도 이 작업은 필요하므로 별도의 메서드 SetMessage를 만들어 호출합시다.
SetMessage();
마찬가지로 확인 버튼을 클릭 시 전체 컨트롤 상태에 따라 메시지를 나타내는 부분도 별도의 메서드 SetResult를 만들어 호출합시다.
SetResult(); } private void SetMessage() {
lb_msg의 Text 속성을 빈 상태로 설정합니다.
lb_msg.Text = string.Empty;
cb_car 컨트롤의 Checked 속성에 따라 자동차 소유 유무를 설정합니다.
if (cb_car.Checked) { lb_msg.Text += "자동차 소유"; } else { lb_msg.Text += "자동차 없음"; }
cb_house 컨트롤의 Checked 속성에 따라 집의 소유 유무를 설정합니다. 이 때는 앞에서 설정한 값을 유지하기 위해 앞의 메시지에 붙이는 형태로 설정합니다.
if (cb_house.Checked) { lb_msg.Text += ", 집 소유"; } else { lb_msg.Text += ", 집 없음"; } } private void SetResult() {
lb_msg의 Text 속성은 실시간으로 나타내기로 했습니다. 따라서 소유 메시지는 lb_msg의 Text 속성으로 설정합니다.
lb_own.Text = lb_msg.Text; if(is_female) { lb_gender.Text = "성별 : 여"; } else { lb_gender.Text = "성별 : 남"; } lb_blood.Text = "혈액형 : "+blood.ToString(); }
자동차 소유와 집 소유에 관한 CheckBox에서는 실시간으로 lb_msg의 Text 속성에 나타내기로 했습니다. 그리고 이를 위해 SetMessage 메서드도 정의하였습니다. 두 개의 컨트롤에 CheckedChanged 이벤트 핸들러는 같은 이름으로 추가합시다.
private void cb_CheckedChanged(object sender, EventArgs e) { SetMessage(); }
성별은 여성 혹은 남성 중에 선택할 수 있습니다. 그리고 멤버 필드로 여성인지 확인하는 is_female이 있습니다. 어느 것을 선택하든 rbtn_female의 체크 상태만 확인하는 것으로 원하는 작업을 할 수 있습니다. 성별에 관한 두 개의 RadioButton도 같은 이벤트 핸들러로 등록합시다.
private void rb_gender_CheckedChanged(object sender, EventArgs e) { is_female = rb_female.Checked; }
혈액형은 어느 버튼을 눌렀는지에 따라 멤버 필드 blood를 설정해야 합니다. 여기서도 모두 같은 이벤트 핸들러로 등록합시다.
private void rb_blood_CheckedChanged(object sender, EventArgs e) {
어느 RadioButton의 Checked 상태가 변한 것인지 sender를 RadioButton으로 참조합니다.
RadioButton rbtn = sender as RadioButton;
만약 체크 상태가 false이면 아무 것도 수행하지 않습니다.
if (rbtn.Checked == false) { return; }
그렇지 않다면 어느 RadioButton을 눌렀는지 확인하기 위해 Text 속성을 사용합니다. 그리고 Text 속성에 따라 blood 값을 설정합니다.
switch (rbtn.Text) { case "O": blood = Blood.BLOOD_O; break; case "A": blood = Blood.BLOOD_A; break; case "B": blood = Blood.BLOOD_B; break; case "AB": blood = Blood.BLOOD_AB; break; } }
마지막으로 확인 버튼의 클릭 이벤트 핸들러를 등록하여 SetResult 메서드를 호출합니다.
private void btn_check_Click(object sender, EventArgs e) { SetResult(); }
이제 빌드한 후 정상적으로 동작하는지 확인하세요.
▷Form1.cs
using System; using System.Windows.Forms; namespace Ex_CheckBoxAndRadioButton { public partial class Form1 : Form { enum Blood { NONE, BLOOD_O, BLOOD_A, BLOOD_B, BLOOD_AB } bool is_female; Blood blood; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { Init(); } private void btn_init_Click(object sender, EventArgs e) { Init(); } private void Init() { is_female = true; blood = Blood.BLOOD_O; cb_car.Checked = cb_house.Checked = false; rb_female.Checked = rb_o.Checked = true; SetMessage(); SetResult(); } private void SetMessage() { lb_msg.Text = string.Empty; if (cb_car.Checked) { lb_msg.Text += "자동차 소유"; } else { lb_msg.Text += "자동차 없음"; } if (cb_house.Checked) { lb_msg.Text += ", 집 소유"; } else { lb_msg.Text += ", 집 없음"; } } private void SetResult() { lb_own.Text = lb_msg.Text; if(is_female) { lb_gender.Text = "성별 : 여"; } else { lb_gender.Text = "성별 : 남"; } lb_blood.Text = "혈액형 : "+blood.ToString(); } private void cb_CheckedChanged(object sender, EventArgs e) { SetMessage(); } private void rb_gender_CheckedChanged(object sender, EventArgs e) { is_female = rb_female.Checked; } private void rb_blood_CheckedChanged(object sender, EventArgs e) { RadioButton rbtn = sender as RadioButton; if (rbtn.Checked == false) { return; } switch (rbtn.Text) { case "O": blood = Blood.BLOOD_O; break; case "A": blood = Blood.BLOOD_A; break; case "B": blood = Blood.BLOOD_B; break; case "AB": blood = Blood.BLOOD_AB; break; } } private void btn_check_Click(object sender, EventArgs e) { SetResult(); } } }