[Windows Forms 응용 with C#] 4.4.4 MainForm 구현

프로젝트 생성할 때 디폴트로 만들어주는 Form1의 이름을 MainForm으로 변경하세요. 솔루션 탐색기에서 변경하면 마법사에서 클래스 이름을 자동으로 변경합니다.

MainForm에는 도서 목록을 표시할 ListView 컨트롤과 등록, 자세히 보기, 삭제, 변경할 때 사용할 Button 컨트롤을 추가하세요.

[그림 4.9] MainForm 자식 컨트롤 배치

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

NoName컨트롤 형식설명
1lv_diaryListView도서 목록(View: Details)
2btn_regButton등록
3btn_verifyButton자세히보기
4btn_removeButton삭제
5btn_modifyButton x변경

MainForm에서 세 개의 폼을 띄우는 작업을 수행합니다. 이 때 각각의 폼은 하나씩만 뜨게 구현할 것입니다. 이를 위해 멤버를 선언합시다.

RegForm rf = null;
VerifyForm vf = null;
ModifyForm mf = null;

도서 관리자 개체를 쉽게 사용할 수 있게 속성을 정의합시다.

BookManager BM
{
    get
    {
        return BookManager.BM;
    }
}

MainForm의 Load  이벤트 핸들러를 등록하세요.

private void MainForm_Load(object sender, EventArgs e)
{

도서 관리자 개체에 도서 추가/삭제, 변경 이벤트 핸들러를 등록합니다.

    BM.OnAddBS += new AddEventHandler(BM_OnAddBS);
    BM.OnModifyBS += new ModifyEventHandler(BM_OnModifyBS);
}

void BM_OnModifyBS(object sender, ModifyEventArgs e)
{

도서 변경 이벤트 핸들러에서는 도서 목록에서 이벤트 인자로 받은 일련번호와 같은 항목을 찾습니다.

    foreach (ListViewItem lvi in lv_diary.Items)
    {
        if (lvi.Text == e.No.ToString())
        {

날짜 항목을 이벤트 인자로 받은 값으로 설정합니다.

            lvi.SubItems[2].Text = e.DT.ToShortDateString();
            return;
        }
    }
}

void BM_OnAddBS(object sender, AddEventArgs e)
{
    if (e.IsAdded)
    {

이벤트 인자의 IsAdded 속성이 참이면 도서를 추가했다는 통보입니다. 이벤트 인자의 일련번호, 제목, 날짜로 문자열 배열 개체를 생성합니다. 그리고 생성한 배열 개체를 입력 인자로 ListViewItem 개체를 만들어 ListView 항목에 추가합니다.

        string[] strs = new string[3]
                           {e.No.ToString(), e.Title,e.DT.ToShortDateString()};
        ListViewItem lvi = new ListViewItem(strs);
        lv_diary.Items.Add(lvi);
    }
    else
    {

이벤트 인자의 IsAdded 속성이 거짓이면 도서를 삭제했다는 통보입니다.

        foreach (ListViewItem lvi in lv_diary.Items)
        {
            if (lvi.Text == e.No.ToString())
            {

리스트 뷰에서 일련 번호가 같은 항목을 찾아 제거합니다.

                lv_diary.Items.Remove(lvi);
                return;
            }
        }

만약 목록에 없는 도서 삭제 이벤트를 통보 받았다면 프로그램에 버그가 있는 것입니다. 버그를 빨리 발견할 수 있게 예외를 던집니다.

        throw new ApplicationException("목록에 없는 삭제 이벤트를 통보 받음");
    }
}

등록 버튼의 Click 이벤트 핸들러를 등록합니다.

private void btn_reg_Click(object sender, EventArgs e)
{

RegForm 개체가 없을 때만 생성합니다.

    if (rf == null)
    {
        rf = new RegForm();

RegForm 이 닫힐 때를 알아야 하므로 FormClosed 이벤트 핸들러를 등록합니다.

        rf.FormClosed += new FormClosedEventHandler(Sub_FormClosed);
        rf.Show();
    }
}

void Sub_FormClosed(object sender, FormClosedEventArgs e)
{

이벤트 게시자를 Form 형식 개체로 참조합니다.

    Form form = sender as Form;

폼이 누구인지를 확인하여 해당 멤버를 null로 설정합니다.

    if (form.Equals(rf))
    {
        rf = null;
    }
    if (form.Equals(vf))
    {
        vf = null;
    }
    if (form.Equals(mf))
    {
        mf = null;
    }
}

자세히 버튼과 변경 버튼에도 클릭 이벤트 핸들러를 등록하세요. 해야 할 작업은 등록 버튼의 클릭 이벤트 핸들러와 논리가 같습니다.

private void btn_verify_Click(object sender, EventArgs e)
{
    if (vf == null)
    {
        vf = new VerifyForm();
        vf.FormClosed += new FormClosedEventHandler(Sub_FormClosed);
        vf.Show();
    }
}
private void btn_modify_Click(object sender, EventArgs e)
{
    if (mf == null)
    {
        mf = new ModifyForm();
        mf.FormClosed += new FormClosedEventHandler(Sub_FormClosed);
        mf.Show();
    }
}

도서 목록 리스트 뷰의 SelectedIndexChanged 이벤트 핸들러를 등록하세요.

private void lv_diary_SelectedIndexChanged(object sender, EventArgs e)
{

만약 선택항목이 없으면 삭제 버튼을 비활성화하고 있으면 활성화합니다.

    btn_remove.Enabled = (lv_diary.SelectedItems.Count != 0);
}

삭제 버튼의 Click 이벤트 핸들러를 등록하세요.

private void btn_remove_Click(object sender, EventArgs e)
{
    if (lv_diary.SelectedItems.Count == 0)
    {

선택 항목이 없는데 삭제 이벤트를 통보받았다면 프로그램 버그입니다. 예외를 던져 빠르게 버그를 발견할 수 있게 합시다.

        throw new ApplicationException("선택 항목이 없는데 삭제 요청");
    }

선택 항목의 일련 번호를 구합니다.

    ListViewItem lvi = lv_diary.SelectedItems[0];
    int no = int.Parse(lvi.Text);

도서 관리자 개체의 RemoveBS 메서드를 호출하여 도서를 삭제 요청합니다.

    BM.RemoveBS(no);
}