[Windows Forms 응용 with C#] 2.2 CheckBox와 RadioButton 사용 실습

CheckBox와 RadioButton도 Button 컨트롤 만큼 자주 사용하는 컨트롤입니다. 두 개의 컨트롤은 모두 체크 상태를 속성으로 갖는 컨트롤입니다. 특히 RadioButton은 여러 개의 항목 중에 하나의 항목만 체크 상태를 갖을 수 있는 특징을 갖고 있습니다.

CheckBox와 RadioButton 컨트롤을 사용할 때 프로그램 방식으로 상태를 변경할 수도 있어야 하며 현재 체크 상태를 파악할 수 있어야 할 것입니다. 또한 사용자에 의해 체크 상태가 바뀌는 시점도 알 수 있어야 합니다.

이번에 실습에서 만들 프로젝트에는 자동차, 집의 소유 유무를 설정할 CheckBox 컨트롤과 성별과 혈액형을 설정할 수 있는 RadioButton으로 구성합니다. 두 개의 체크 박스를 클릭하여 체크 상태가 바뀌면 Label에 이들의 체크 상태를 표시합니다. 그리고 확인 버튼을 누르면 CheckBox와 RadioButton의 체크 상태에 따라 Label에 메시지를 표시합니다. 마지막으로 초기화 버튼을 누르면 초기 상태로 변합니다.

[그림 2.4] 컨트롤 배치

다음은 Form1의 자식 컨트롤 Name과 형식입니다.

NoName컨트롤 형식설명
1cb_carCheckBox자동차 소유
2cb_houseCheckBox집 소유
3gbox_genderGroupBox성별 그룹 박스
4rbtn_femaleRadioButton여성
5rbtn_maleRadioButton남성
6gbox_bloodGroupBox혈액형 그룹 박스
7rbtn_oRadioButtonO 형
8rbtn_aRadioButtonA 형
9rbtn_bRadioButtonB 형
10rbtn_abRadioButtonAB 형
11lb_msgLabel소유 상태를 실시간으로 알려주는 메시지
12btn_checkButton현재 상태 확인
13btn_initButton전체 상태 초기화
14lb_ownLabelbtn_check 클릭 시 소유 정보 나타냄
15lb_genderLabelbtn_check 클릭 시 성별 정보 나타냄
16lb_bloodLabelbtn_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();
        }
    }
}