06
17

1) 메뉴

윈폼 애플리케이션에서 가장 일반적인 사용자 인터페이스로 윈폼 애플리케이션이 제공하는 기능을 사용자가 쉽게 이해하고 사용할 수 있도록 도와주는 기능이다.

 

메뉴의 종류

  • 메인 메뉴(main menu) : 폼의 상단에 배치되는 주요 메뉴
  • 상황 메뉴(context menu) : 마우스 오른쪽 버튼을 클릭했을 때 나타나는 팝업 메뉴

1.1) 메인메뉴

메인 메뉴는 폼의 상단에 배치되는 메뉴로 마우스 클릭뿐만 아니라 단축키를 통해서는 접근할 수 있는 가장 기본적인 사용자 인터페이스이다. 통합 개발 환경의 MenuStrip 컴포넌트를 통하여 작성한다.

 

메뉴 항목의 추가 : 메뉴에 단축 문자를 부여하기 위한 방법

  • 사용할 단축문자 앞에 &를 붙임
  • Alt 키와 단축 문자를 눌러서 메뉴의 선택이 가능

메뉴 항목의 단축키 적용 : 단축키를 적용할 메뉴 항목을 선택

 

구분선 : 메뉴 항목을 그룹화하기 위해 구분선을 사용하며 메뉴 항목에 '-'를 입력하면 된다.

 

이벤트

  • Click : 메뉴 항목을 클릭했을 때 발생하며 메뉴와 관련된 이벤트 중에서 가장 많이 사용하는 이벤트이다.
  • MenuStart : 메뉴가 처음으로 입력 포커스를 얻을 때 발생하며 폼의 사용자 인터페이스르 관리하기 위해서 사용한다.
  • MenuComplete : 메뉴가 입력 포커스를 잃을 때 발생하며 메뉴가 사라지는 순간을 확인하기 위해 사용한다.

단축문자

단축 문자는 메뉴 항목의 이름에 &를 붙인 형태로 메뉴 표시줄에 나타나는 메인 메뉴 사이에서는 반드시 유일해야 한다. 메인 메뉴의 서로 다른 메뉴 항목에 대해서는 중복 사용이 가능하다. 

 

단축키

단축키는 메뉴항목의 Shortcut 프로퍼티를 통해 설정한다. 단축키는 하나의 애플리케이션에 포함된 모든 메뉴 항목에 대하여 유일하도록 설정한다. 중복하여 설정할 경우, 두 번째 이후로 설정된 메뉴 항목의 단축키는 반영되지 않는다.

 

ex)

private void MnuNewFile_Click(object sender, EventArgs e)
{
	textBox1.Text = textBox1.Text + MnuNewFile.Text + Environment.NewLine;
	//실제 새 파일 로직을 입력해야함
}

private void 열기OToolStripMenuItem_Click(object sender, EventArgs e)
{
	textBox1.Text = textBox1.Text + 열기OToolStripMenuItem.Text + Environment.NewLine;
	//실제 열기 로직을 입력해야함
}

private void 저장SToolStripMenuItem_Click(object sender, EventArgs e)
{
	textBox1.Text = textBox1.Text + 저장SToolStripMenuItem.Text + Environment.NewLine;
	MessageBox.Show("저장했습니다.");
	//실제 저장 로직을 입력해야함
}

private void 종료XToolStripMenuItem_Click(object sender, EventArgs e)
{
	Application.Exit();
}

private void 프로그램정보AToolStripMenuItem_Click(object sender, EventArgs e)
{
	textBox1.Text = textBox1.Text + 프로그램정보AToolStripMenuItem.Text + Environment.NewLine;
	AboutBox aboutBox = new AboutBox();
	aboutBox.ShowDialog();
}

 

예제 실행 화면

 

1.2) 상황 메뉴

상황 메뉴는 컨트롤 위에서 마우스의 오른쪽 버튼을 클릭하였을 때 표시되는 팝업 메뉴로 현재 애플리케이션의 상태가 반영되고 상황에 따라 독자적인 메뉴 항목을 가진다.

 

상황 메뉴의 작성

ComtextMenuStrip 컴포넌트를 추가하면 된다. 상황 메뉴는 메인 메뉴와 동일한 프로퍼티와 이벤트를 가지며 완성된 상황 메뉴를 해당 폼 또는 컨트롤의 ContextMenu 프로퍼티에 설정하면 된다. 컨트롤마다 상황 메뉴를 가질 수 있기 때문에 적용하고자 하는 컨트롤의 ContextMenu 프로퍼티에 설정해야 한다.

 

ex)

private void TextBox1_MouseClick(object sender, MouseEventArgs e)
{
	if(e.Button == MouseButtons.Right)
	{
		contextMenuStrip1.Show(e.Location);
	}
}

 

예제 실행 화면

 

cf. toolStrip, StatusStrip

 

ex)

private void toolStripButton1_Click(object sender, EventArgs e)
{
	MnuNewFile_Click(sender, e);
}

 

 

private void MnuNewFile_Click(object sender, EventArgs e)
{
	textBox1.Text = textBox1.Text + MnuNewFile.Text + Environment.NewLine;
	toolStripStatusLabel1.Text = MnuNewFile.Text;
	//실제 새 파일 로직을 입력해야함
}

 

 

2) 마우스

마우스는 윈도우 사용자에게 가장 편리하고 친숙한 입력장치로 윈폼 애플리케이션의 사용자 상호작용은 대부분 마우스를 통해 이루어진다. 사용자가 마우스를 이동하거나 클릭하면 이벤트가 발생한다. 마우스 이벤트에는 사용자가 마우스의 위치를 이동시킬 경우 발생하는 이동 이벤트와 사용자가 마우스의 버튼을 클릭할 경우 발생하는 선택 이벤트가 있다.

 

마우스 이동 이벤트

  • MouseEnter : 마우스 포인터가 컨트롤이나 폼 영역에 들어올 때 발생
  • MouseHover : 마우스 포인터가 컨트롤이나 폼에서 이동하는 것을 멈출 때 발생, 매번 발생하지 않으며 처음 멈출 때만 발생
  • MouseLeave : 마우스 포인터가 컨트롤이나 폼 영역을 벗어날 때 발생
  • MouseMove : 마우스 포인터가 새로운 영역으로 이동할 때 발생
  • MouseWheel : 입력 포커스를 가지고 있는 컨트롤이나 폼 위에서 마우스 휠 버튼을 회전시킬 때 발생

마우스 좌표는 왼쪽 위부터 0,0이다.

 

2.1) MouseEventArgs 클래스의 프로퍼티

Button : 마우스의 상태를 나타내는 MouseButtons 열거형 값

 

MouseButtons 열거형

  • Left : 마우스 왼쪽 버튼을 클릭한 상태
  • Middle : 마우스 중앙 버튼을 클릭한 상태
  • None : 마우스를 누르지 않은 상태
  • Right : 마우스 오른쪽 버튼을 클릭한 상태
  • XButton1 : 첫 번째 X버튼을 클릭한 상태
  • XButton2 : 두 번째 X버튼을 클릭한 상태

Clicks : 마우스 버튼을 클릭한 횟수

Delta : 마우스 휠의 회전수(휠을 1회 돌리는 것)를 나타내는 값

X : 클라이언트 좌표 내에서, 마우스 위치의 X좌표

Y : 클라이언트 좌표 내에서, 마우스 위치의 Y좌표

 

2.2) 마우스 선택 이벤트

  • MouseDown : 폼이나 컨트롤에서 마우스 버튼을 누를 때 발생
  • MouseUp : 폼이나 컨트롤에서 마우스 버튼을 누른 후 해제할 때 발생
  • Click : 폼이나 컨트롤을 클릭할 때 발생
  • DoubleClick : 폼이나 컨트롤을 더블 클릭할 때 발생

2.3) 마우스 이벤트의 발생 순서

마우스의 이벤트가 비동기적으로 불특정 시간에 발생하더라도 상대적인 순서는 보장된다.

  • MouseEnter와 MouseLeave 사이에 발생하는 이벤트 : MouseHover, MouseMove
  • Click 이벤트 : MouseDown과 MouseUp 이벤트 다음에 발생
  • DoubleClick 이벤트 : Click 이벤트 다음에 발생

ex)

private void textBox1_MouseMove(object sender, MouseEventArgs e)
{
	LblMouseLocation.Text = $"X좌표 : {e.X.ToString()}, Y좌표 : {e.Y.ToString()}";
}

 

예제 실행 화면

 

3) 입력 포커스

입력 포커스는 키보드를 통해 입력이 가능한 컨트롤을 표시한다. 키보드를 이용한 사용자의 입력은 여러 개의 컨트롤에서 동시에 사용할 수 없다. 입력 포커스를 가지는 컨트롤만이 키보드를 통해 사용자의 입력을 받을 수 있다. 입력 포커스를 가지는 컨트롤은 자신의 형태를 변경한다.

 

3.1) Focus() 메서드

  • 특정 컨트롤로 입력 포커스를 이동시키기 위한 메서드
  • Control 클래스로부터 파생된 대부분의 컨트롤이 가지는 메서드
  • 특정 컨트롤에 대한 포커스가 변경될 경우, 참을 반환
  • 특정 컨트롤에 대한 포커스가 변경되지 못할 경우, 거짓을 반환

3.2) 입력 포커스와 관련된 프로퍼티

  • 대부분의 컨트롤에서 공통적으로 제공
  • CanFocus : 컨트롤이 포커스를 받을 수 있는지 여부를 나타내는 값을 가져옴
  • ContainFocus : 컨트롤이나 해당 컨트롤의 자식 컨트롤이 현재 입력 포커스를 가지고 있는지 여부를 나타내는 값을 가져옴
  • Focused : 컨트롤에 입력 포커스가 있는지 여부를 나타내는 값을 가져옴

3.3) 입력 포커스와 관련된 이벤트

  • Enter : 자신 또는 자식 컨트롤이 입력 포커스를 가질 때 발생
  • Leave : 자신 또는 자식 컨트롤이 입력 포커스를 잃을 때 발생
  • Enter, Leave 이벤트를 이용하면 특정 컨트롤이 입력 포커스를 받았음을 알릴 수 있도록 사용자 인터페이스를 변경할 수 있음

 

ex)

private void Form1_Activated(object sender, EventArgs e)
{
	button1.Focus();
}

 

예제 실행 화면

 

4) 키보드

윈폼 애플리케이션은 사용자로부터 직접 키보드 입력을 받지 않는다. 텍스트 박스와 같은 컨트롤을 이용하여 키보드 입력이 이루어진다.

 

4.1) 키보드 이벤트

  • KeyDown : 사용자가 키를 누를 때 발생, 키 상태와 보조키를 위한 Keys 열거형 정보를 사용할 수 있음
  • KeyPress : 키가 완전히 눌러진 상태에서 발생, 키 문자에 대한 정보를 사용할 수 있음
  • KeyUp : 키를 떼었을 때 발생, 키 상태와 보조키를 위한 Keys 열거형 정보를 사용할 수 있음
  • 이벤트 발생 순서 : KeyDown → KeyPress → KeyUp

4.2) KeyDown, KeyUp 이벤트 처리기

KeyEventArgs 클래스의 객체를 매개 변수로 가짐, KeyEventArgs 클래스는 키보드 입력을 직접 처리할 수 있는 프로퍼티

프로퍼티 설명
Alt  <Alt> 키를 눌렀는지 여부를 나타내는 값을 가져옴
Control  <Ctrl> 키를 눌렀는지 여부를 나타내는 값을 가져옴
Handled  이벤트가 처리되었는지 여부를 나타내는 값을 가져오거나 설정
KeyCode  KeyDown 또는 KeyUp 이벤트에 대한 키보드 코드를 가저옴
KeyData  KeyDown 또는 KeyUp 이벤트에 대한 키 데이터를 가져옴
KeyValue  KeyDown 또는 KeyUp 이벤트에 대한 키보드 값을 가져옴
Modifiers  KeyDown 또는 KeyUp 이벤트에 대한 보조 플래그를 가져옴
 이는 누른 보조키(<Ctrl>, <Shift>, <Alt>)의 조합을 나타냄
Shift  <Shift> 키가 눌렀는지 여부를 나타내는 값을 가져옴

키의 상태와 보조키에 대한 정보를 쉽게 얻을 수 있다.

 

4.3) KeyPress 이벤트 처리기

KeyPressEventArgs 클래스의 객체를 매개변수로 가짐

  • KeyPressEventArgs 클래스는 키 코드와 보조키에 대한 정보 대신에 눌려진 문자 값을 처리할 수 있는 프로퍼티를 제공
  • KeyChar 프로퍼티는 사용자가 누른 키의 실제 문자 값을 반환
프로퍼티 설명
Handled  이벤트가 처리되었는지 여부를 나타내는 값을 가져오거나 설정
KeyChar  눌러진 문자값

 

ex)

private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
	if(e.KeyChar == 13) // 10 :  Line Feed => 다음 줄로 // 13 : Cariage Return => 제일 처음 칸으로
	{
		button1_Click(sender, new EventArgs());
	}
}

 

엔터를 이용한 입력

 

5) 리스트 뷰

리스트 뷰는 리스트 상자와 유사한 형태를 지니며 목록을 구조적으로 장식할 수 있는 컨트롤이다. View 프로퍼티의 값에 따라 다양한 형태를 가진다.

 

View 열거형

기호상수 설명
LargeIcon  큰 아이콘의 형태
SmallIcon  작은 아이콘의 형태
List  간단한 리스트 형태
Details  자세한 리스트 형태
Tile  큰 아이콘이 표시되는 자세한 리스트 형태

 

5.1) 리스트 뷰 항목의 선택

SelectedItems 프로퍼티 : 리스트 뷰에서 선택된 항목을 저장하는 프로퍼티

리스트 뷰의 MultiSelect 프로퍼티가 참일 경우 ListViewItem 클래스의 배열형을 반환하고 거짓일 경우 ListViewItem 클래스형이 반환된다

 

ex)

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
	switch(comboBox1.SelectedIndex)
	{
		case 0: //LargeIcon
			listView1.View = View.LargeIcon;
			break;
		case 1: //Details
			listView1.View = View.Details;
			break;
		case 2: //SmallIcon
			listView1.View = View.SmallIcon;
			break;
		case 3: //List
			listView1.View = View.List;
			break;
		case 4: //Tile
			listView1.View = View.Tile;
			break;
		default:
			listView1.View = View.Details;
			break;
	}
}

private void listView1_SelectedIndexChanged(object sender, EventArgs e)
{
	foreach(ListViewItem item in listView1.SelectedItems)
	{
		ListViewSubItemCollection subItem = item.SubItems;
		label1.Text = $"{item.Text}의 국가번호는 {subItem[1].Text}";
	}
}

 

예제 실행 화면

 

6) 트리 뷰

트리 뷰는 목록(노드)을 계층적으로 보여주기 위한 컨트롤로 노드에 이미지 아이콘을 추가할 수 있다. 트리 뷰의 노드는 트리 노드 편집기를 통해 생성하며 TreeNode 클래스의 객체이다. TreeView 컨트롤의 Nodes 프로퍼티에 TreeNodeCollection 형으로 저장한다. TreeNodeCollection 클래스의 메서드를 통해 노드의 편집이 가능하다.

메서드 설명
Add(TreeNode node)  트리 뷰에 새로운 노드를 추가
Clear()  트리 뷰의 모든 노드를 삭제
Insert(int index, TreeNode node)  트리 뷰의 지정된 인덱스에 노드를 삽입
Remove(TreeNode node)  트리 뷰의 노드 중 매개 변수에 해당하는 노드를 삭제

트리 뷰의 노드는 TreeNode 클래스의 객체로 TreeNode 클래스의 객체를 생성함으로 추가할 수 있다.

public TreeNode(string label);
public TreeNode(string label, int idx1, int idx2);
//label : 노드 이름에 해당하는 문자열
//idx1 : 노드가 선택되지 않았을 때의 이미지 인덱스
//idx2 : 노드가 선택되었을 때의 이미지 인덱스

 

6.1) 트리 뷰 항목의 선택

SelectedNode 프로퍼티 : 트리 뷰에서 선택된 노드를 저장하는 프로퍼티로 반환형은 TreeNode 클래스형이다

TreeNode 클래스의 프로퍼티를 이용하면 선택된 노드를 기준으로 부모 이전 형제, 다음 형제, 자식 노드를 참조할 수 있다.

메서드 설명
Parent  현재 트리 노드의 부모 노드
PreNode  현재 트리 노드의 이전 형제 노드
NextNode  현재 트리 노드의 다음 형제 노드
Nodes  현재 트리 노드의 자식 노드들

 

ex)

private void Form1_Activated(object sender, EventArgs e)
{
	//treeView1.ExpandAll(); // 트리 전체 열기
	//treeView1.CollapseAll(); // 트리 전체 닫기
}

private void button1_Click(object sender, EventArgs e)
{
	if(textBox1.Text != "" && treeView1.SelectedNode != null)
	{
		treeView1.SelectedNode.Nodes.Add(new TreeNode(textBox1.Text, 2, 2));
		textBox1.Text = "";
		textBox1.Focus();
	}
	else
	{
		MessageBox.Show("추가할 노드의 이름을 넣고, 노드를 추가할 위치를 선택하세요");
	}
}

private void button2_Click(object sender, EventArgs e)
{
	treeView1.Nodes.Remove(treeView1.SelectedNode);
}

 

예제 실행 화면

 

cf. 루트 노드 추가

private void button3_Click(object sender, EventArgs e)
{
	if (textBox1.Text != "")
	{
		treeView1.Nodes.Add(new TreeNode(textBox1.Text, 0, 1));
		textBox1.Text = "";
		textBox1.Focus();
	}
	else
	{
		MessageBox.Show("추가할 노드의 이름을 넣으세요");
	}
}

 

7) 프로그레스 바

프로그레스 바는 작업의 진행상황을 보여주는 컨트롤이며 좌측에서 우측으로 사각형의 조각을 채우면서 진행한다. 애플리케이션의 설치 과정이나 파일 복사 과정에서 사용한다. 도구 상자의 ProgressBar를 선택하여 폼에 추가하며 프로그레스 바의 프로퍼티(Maximum, Minimum)를 통해 값에 대한 범위를 설정한다.

 

ex)

private void button1_Click(object sender, EventArgs e)
{
	progressBar1.Value = 0;
	for(int i = 0 ; i < progressBar1.Maximum ; i++)
	{
		progressBar1.Value = progressBar1.Value + 1;
	}
}

 

예제 실행 화면

 

8) 타이머

타이머는 주기적인 간격으로 이벤트를 발생시키는 컴포넌트다. 배경 작업을 처리할 때 주로 사용하며 일정한 간격에 따라 Tick 이벤트를 발생시킨다. 이는 Interval 프로퍼티를 통해 간격을 설정할 수 있으며 밀리 초(millisecond, 1/1000초)를 사용한다. 주기적으로 발생시키기 위해서는 Enable 프로퍼티를 참으로 설정하면 된다. 그러나 Tick 이벤트가 다른 이벤트에 비해 우선순위가 낮기 때문에항상 Interval 프로퍼티의 간격에 따라 Tick 이벤트가 발생하는 것은 아니다. 

 

ex)

private int index = 0;

private void timer1_Tick(object sender, EventArgs e)
{
	index = index % imageList1.Images.Count;
	label1.Image = imageList1.Images[index];
	index++;
}

private void Form1_Load(object sender, EventArgs e)
{
	timer1.Enabled = true;
}

 

예제 실행 화면

9) 그래픽

Graphics(System.Drawing.Graphics) 클래스에는 선, 사각형, 타원 등과 같은 도형을 그리는데 필요한 기본적인 메서드들이 존재한다. 그래픽 객체는 도형을 그리기 위해 필요한 Graphics 클래스의 객체로 그리기 판이 되는 대상이다. 객체를 얻거나 생성하는 방법은 Paint 이벤트 처리기의 매개변수, Control 클래스의 CreateGraphics() 메서드, Graphics.FromImage() 메서드가 있다.

 

그래픽에 대한 정보는 아래의 파일 참고.

cs12.pdf
1.46MB

ex)

 private void Form1_Paint(object sender, PaintEventArgs e)
{
	Graphics g = CreateGraphics();
	Pen pen = new Pen(Color.DeepPink);
	Point startPoint = new Point(45, 45);
	Point endPoint = new Point(180, 150);

	pen.Width = 5.0f;
	pen.DashStyle = System.Drawing.Drawing2D.DashStyle.DashDotDot;

	g.DrawLine(pen, startPoint, endPoint);

	//g.DrawLine(pen, new Point(190,60), new Point(65,170));
	g.DrawLine(pen, 190, 60, 65, 170);
}

 

예제 실행 화면

 

Graphics g = CreateGraphics();
Rectangle rect = new Rectangle(50, 50, 150, 100);
g.FillRectangle(Brushes.Lime, rect);

 

예제 실행 화면

 

private void Form1_Paint(object sender, PaintEventArgs e)
{
	Graphics g = CreateGraphics();
	Rectangle rect = new Rectangle(50, 50, 150, 100);
	g.FillRectangle(Brushes.Lime, rect);
	Pen pen = new Pen(Color.DeepPink);
	pen.Width = 5.0f;
	pen.DashStyle = System.Drawing.Drawing2D.DashStyle.DashDotDot;
	g.DrawRectangle(pen, rect);
}

 

예제 실행 화면

 

private void Form1_Paint(object sender, PaintEventArgs e)
{
	Graphics g = CreateGraphics();
	Pen pen = new Pen(Color.DeepPink);
	pen.Width = 5.0f;
	Rectangle[] rects = new Rectangle[]
	{
		new Rectangle(40,40,40,100),
		new Rectangle(100,40,100,40),
		new Rectangle(100,100,100,40)
	};
	g.FillRectangles(Brushes.Violet, rects);
	g.DrawRectangles(pen, rects);
}

 

예제 실행 화면

 

private void Form1_Paint(object sender, PaintEventArgs e)
{
	Graphics g = CreateGraphics();
	Point[] pts =
	{
		new Point(115,30), new Point(140, 90),
		new Point(200,115), new Point(140, 140),
		new Point(115,200), new Point(90, 140),
		new Point(30,115), new Point(90, 90)
	};
	g.FillClosedCurve(Brushes.Yellow, pts);
	g.DrawClosedCurve(Pens.Black, pts);
}

 

예제 실행 화면

 

cf. 참고 파일

cs10.pdf
1.74MB
cs11.pdf
1.90MB

COMMENT