Notice
Recent Posts
Recent Comments
Link
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Archives
Today
Total
관리 메뉴

nomad-programmer

[Programming/C#] WinForm : Form Designer 본문

Programming/C#

[Programming/C#] WinForm : Form Designer

scii 2020. 10. 3. 02:15

폼 디자이너를 이용한 WinForm UI 구성

비주얼 스튜디오는 사용하기 쉬우면서 강력한 폼 디자이너를 제공한다. 폼 디자이너는 비주얼 스튜디오 IDE의 일부로, 코드를 통해 컨트롤을 폼 위에 배치하고 프로퍼티를 변경했던 작업을 마우스 클릭만으로 가능하게 해준다.

Qt의 Qt Designer 와 같다고 생각하면 된다.

폼 디자이너는 새 프로젝트를 "Windows Form 응용 프로그램" 템플릿을 선택하여 만들면 나타난다.

폼 디자이너는 도구 상자와 함께 사용해야 한다. 이 도구 상자에는 WinForm에서 제공하는 수많은 컨트롤들을 담고 있어서 "컨트롤 팔레트(Control Palette)"라는 이름으로 불리기도 한다.


Step 1. GroupBox 컨트롤부터 배치한 뒤 그림에서 보이는 것처럼 컨트롤들을 배치한다.

윈도우 폼 디자이너

컨트롤 배치를 마치면 각 이 컨트롤에 이벤트 처리기를 등록할 차례이다. 다른 컨트롤보다도 MainForm의 Load 이벤트에 대한 처리기를 먼저 등록한다. 이 이벤트가 다른 어떤 컨트롤의 이벤트보다도 가장 먼저 발생할 이벤트이기 때문이다.
폼 디자이너에서 MainForm을 선택하고 속성 창에서 <이벤트> 버튼(번개 아이콘)을 클릭하여 Form 컨트롤의 이벤트 목록을 연다. 그리고 이벤트 목록에서 'Load' 항목을 찾아 더블 클릭한다.

여기까지 작업했다면 IDE가 MainForm_Load() 이벤트 처리기의 껍데기를 만들면서 코드 편집창을 자동으로 열어준다. 이곳에 다음과 같이 코드를 추가해서 이벤트 처리기를 완성해준다.

Step 1. 폰트 콤보박스 초기화

private void MainForm_Load(object sender, EventArgs e)
{
    // 운영체제에 설치되어 있는 폰트 목록 검색
    FontFamily[] fonts = FontFamily.Families;

    // 콤보박스 컨트롤에 각 폰트 이름 추가
    foreach(FontFamily font in fonts)
    {
        cboFont.Items.Add(font.Name);
    }
}

Step 2. 문자열 폰트를 변경하는 메소드 작성

private void ChangeFont()
{
    // 콤보박스에서 선택한 항목이 없으면 메소드 종료
    if (cboFont.SelectedIndex < 0)
    {
        return;
    }
    // 객체 초기화
    FontStyle style = FontStyle.Regular;

    // 굵게 체크 박스가 선택되어 있으면 Bold 논리합 수행
    if (chkBold.Checked)
    {
        style |= FontStyle.Bold;
    }
    // 이탤릭 체크 박스가 선택되어 있으면 Italic 논리합 수행
    if (chkItalic.Checked)
    {
        style |= FontStyle.Italic;
    }

    // SampleText의 Font 프로퍼티를 앞에서 만든 style로 수정
    txtSampleText.Font = new Font((string)cboFont.SelectedItem, 10, style);
}

Step 3. 각 컨트롤에 대한 이벤트 처리기를 만든다. 해당 컨트롤에서 더블 클릭하면 자동으로 만들어진다.

private void cboFont_SelectedIndexChanged(object sender, EventArgs e)
{
    ChangeFont();
}

private void chkBold_CheckedChanged(object sender, EventArgs e)
{
    ChangeFont();
}

private void chkItalic_CheckedChanged(object sender, EventArgs e)
{
    ChangeFont();
}

Step 4. <F5> 키를 눌러 프로그램을 디버깅 모드로 실행하여 테스트해본다.


TrackBar, ProgressBar

GroupBox 컨트롤부터 배치한 뒤 나머지 컨트롤을 배치한다.

private void tbDummy_Scroll(object sender, EventArgs e)
{
    // 슬레이더의 위치에 따라 프로그래스바의 내용도 변경
    pgDummy.Value = tbDummy.Value;
}

TrackBar와 ProgressBar 컨트롤을 추가한 모습


Button, Form, Dialog

Modal 그리고 Modaless

윈도우 프로그램은 두 가지 모드 자식 창을 띄울 수 있다. 그 중 한 가지가 Modal이고, 또 다른 한 가지가 Modaless이다.

* Modal 창은 일단 띄우고 나면 창을 닫을 때까지 프로그램의 다른 UI를 절대 사용할 수 없다는 것이 특징이다. 프로그램이 심각한 정보를 표시해야 하거나 사용자로부터 중요한 결정 사항을 입력받아 다음 단계를 진행해야 할 때 주고 사용한다.

* Modaless 창은 띄우고 난 뒤에도 프로그램의 다른 UI에 사용자가 접근할 수 있다. 웹 브라우저의 파일 다운로드 창이 Modaless 창의 좋은 예다. 파일을 다운로드하면 자식 창이 떠서 파일 다운로드를 수행하지만 사용자는 여전히 웹 브라우저로 다른 페이즈를 탐색할 수 있다.

컨트롤을 배치하고 프로퍼티를 변경한다. Click 이벤트로 이벤트 처리를 진행한다.

private void btnModal_Click(object sender, EventArgs e)
{
    Form frm = new Form();
    frm.Text = "Modal Form";
    frm.Width = 300;
    frm.Height = 100;
    frm.BackColor = Color.Red;
    frm.ShowDialog();
}

private void btnModaless_Click(object sender, EventArgs e)
{
    Form frm = new Form();
    frm.Text = "Modaless Form";
    frm.Width = 300;
    frm.Height = 100;
    frm.BackColor = Color.Green;
    frm.Show();
}

private void btnMsgBox_Click(object sender, EventArgs e)
{
    MessageBox.Show(txtSampleText.Text,
        "MessageBox Test", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}

ShowDialog() 메소드와 Show() 메소드로 Modal과 Modaless를 표현한다.

TreeView, ListView

Step 1. 컨트롤을 배치하고 프로퍼티를 변경한다.

폼 디자이너로 이와 같이 만든다.

Step 2. MainForm.cs를 코드 편집기로 열어 다음과 같이 필드 하나를 추가한다. TreeView의 노드 이름으로 사용할 난수 생성기이다.

public partial class MainForm : Form
{
    Random random = new Random(55);
    // ...
}

Step 3. MainForm() Load 이벤트에 lvDummy 컬럼을 생성하는 코드를 입력한다.

private void MainForm_Load(object sender, EventArgs e)
{
    // ...
    
    lvDummy.View = View.Details;
    lvDummy.Columns.Add("Name");
    lvDummy.Columns.Add("Depth");
}

Step 4. TreeToList() 메소드를 추가한다. 이 메소드는 TreeView의 각 노드를 ListView로 옮겨 표시하는 기능을 한다.

void TreeToList()
{
    lvDummy.Items.Clear();
    foreach(TreeNode node in tvDummy.Nodes)
    {
        TreeToList(node);
    }
}

void TreeToList(TreeNode Node)
{
    // TreeNode 형식의 FullPath 프로퍼티는 루트 노드부터
    // 현재 노드까지의 경로를 나타내며, 각 경로는 \로 구분한다.
    lvDummy.Items.Add(
        new ListViewItem(
            new string[] { Node.Text,
            Node.FullPath.Count(f => f =='\\').ToString()}));

    foreach(TreeNode node in Node.Nodes)
    {
        TreeToList(node);
    }
}

Step 5. <루트 추가> 버튼과 <자식 추가> 버튼에 대한 Click 이벤트 처리기를 생성한다.

private void btnAddRoot_Click(object sender, EventArgs e)
{
    tvDummy.Nodes.Add(random.Next().ToString());
    TreeToList();
}

private void btnAddChild_Click(object sender, EventArgs e)
{
    if (tvDummy.SelectedNode == null)
    {
        MessageBox.Show("선택한 노드가 없습니다.",
            "TreeView Test", MessageBoxButtons.OK, MessageBoxIcon.Error);
        return;
    }
    tvDummy.SelectedNode.Nodes.Add(random.Next().ToString());
    tvDummy.SelectedNode.Expand();
    TreeToList();
}

Step 6. <F5> 키를 눌러 프로그램을 디버깅 모드로 실행한다.

Comments