안녕하세요 문쑹입니다 :)
오늘도 열심히 포스팅을 해보겠습니다!
메뉴 다루기
메뉴
윈폼 애플리케이션에서 가장 일반적인 사용자 인터페이스
윈폼 애플리케이션이 제공하는 기능을 사용자가 쉽게 이해하고 사용할 수 있도록 도와주는 기능
메뉴의 종류
메인 메뉴 (main menu) - 폼의 상단에 배치되는 주요 메뉴
상황 메뉴 (context menu) - 마우스 오른쪽 버튼을 클릭했을 때 나타나는 팝업 메뉴
메인 메뉴
- 폼의 상단에 배치되는 메뉴
- 마우스 클릭뿐만 아니라 단축키를 통해서는 접근할 수 있는 가장 기본적인 사용자 인터페이스
- 통합 개발 환경의 MenuStrip 컴포넌트를 통하여 작성
메인 항목의 추가
- 메뉴에 단축문자를 부여하기 위한 방법 (단축문자 앞에 &를 붙임)
메뉴항목의 단축키 적용
- 단축키를 적용할 메뉴 항목을 서택
구분선
- 메뉴 항목을 그룹화하기 위하여 구분선을 사용
- 메뉴 항목에 '-'를 입력
예제를 살펴 보겠습니다.
ShortcutKeys에서 단축키를 설정할 수 있습니다. 위의 예제와 같이 단축키를 설정해보세요!
오른쪽 솔루션 탐색기에서 현재 프로젝트에서 새 항목을 열어주세요
목록들에 보시면 Windows Forms에서 정보 상자를 생성해주세요.
private void 프로그램정보AToolStripMenuItem_Click(object sender, EventArgs e)
{
AboutBox aboutBox = new AboutBox();
aboutBox.ShowDialog();
}
그리고 위의 코드를 입력하고 실행한 후 도움말 - 프로그램 정보에 들어가보시면 아래와 같은 결과 화면이 나옵니다! 이렇게 여러분의 프로그램 정보를 입력하실 수 있습니다.
상황 메뉴
컨트롤 위에서 마우스의 오른쪽 버튼을 클릭하였을 때 표시되는 팝업메뉴
- 현재 애플리케이션의 상태가 반영
- 상황에 따라 독자적인 메뉴 항목을 가짐
ContextMenuStrip 컴포넌트 추가
상황 메뉴는 메인 메뉴와 동일한 프로퍼티와 이벤트를 가진다.
완성된 상황 메뉴를 해당 폼 또는 컨트롤의 ContextMenu 프로퍼티에 설정
private void textBox1_MouseClick(object sender, MouseEventArgs e)
{
if(e.Button == MouseButtons.Right)
{
contextMenuStrip1.Show();
}
}
마우스
윈도우 사용자에게 가장 편리하고 친숙한 입력장치
윈폼 애플리케이션의 사용자 상호작용은 대부분 마우스를 통해 이루어진다.
사용자가 마우스를 이동하거나 클릭하면 이벤트가 발생
마우스 이벤트
이동 이벤트 - 사용자가 마우스의 위치를 이동시킬 경우 발생
선택 이벤트 - 사용자가 마우스의 버튼을 클릭할 경우 발생
마우스 이동 이벤트
MouseEnter
- 마우스 포인터가 컨트롤이나 폼 영역에 들어올 때 발생
MouseHover
- 마우스 포인터가 컨트롤이나 폼에서 이동하는 것을 멈출 때 발생
- 매번 발생하지 않으며 처음 멈출 때만 발생
MouseLeave
- 마우스 포인터가 컨트롤이나 폼 영역을 벗어날 때 발생
MouseMove
- 마우스 포인터가 새로운 영역으로 이동할 때 발생
MouseWheel
- 입력포커스를 가지고 있는 컨트롤이나 폼 위에 마우스 휠 버튼을 회전시킬 때 발생
마우스 이동 이벤트 처리기
EventHandler 델리게이트형의 처리기를 사용하는 이벤트
- MouseEnter, MouseHover, MouseLeave
MouseEventHandler 델리케이트형의 처리기를 사용하는 이벤트
- MouseMove, MouseWheel
- MouseEventArgs 클래스가 제공하는 프로퍼티를 이용하여 마우스의 위치와 상태에 대한 추가적인 정보 사용 가능
public delegate void EventHander(object sender, EventArgs e);
public delegate void MouseEventHander(object sender, MouseEventArgs e);
마우스가 이동할 때 마다 좌표가 나타나는 예제를 만들어 보겠습니다.
private void textBox1_MouseMove(object sender, MouseEventArgs e)
{
LblMouseLocation.Text = $"X, Y = ({e.X},{e.Y})";
}
마우스가 텍스트 박스 안에서 움직일 때 마다 좌표를 표시해줍니다.
입력 포커스
- 키보드를 통해 입력이 가능한 컨트롤을 표시
- 키보드를 이용한 사용자의 입력은 여러 개의 컨트롤에서 동시에 사용할 수 없음
- 입력 포커스를 가지는 컨트롤만이 키보드를 통해 사용자의 입력을 받을 수 있음
- 입력 포커스를 가지는 컴트롤은 자신의 형태를 변경함
Focus() 메소드
- 특정 컨트롤로 입력 포커스를 이동시키기 위한 메소드
- Control 클래스로부터 파생된 대부분의 컨트롤들이 가지는 메소드
- 특정 컨트롤에 대한 포커스가 변경될 경우, 참(True) 반환
- 특정 컨트롤에 대한 포커스가 변경되지 못할 경우, 거짓(False)을 반환
키보드 이벤트
KeyDown
- 사용자가 키를 누를 때 발생
- 키 상태와 보조키를 위한 Keys 열거형 정보를 사용할 수 있음
KeyPress
- 키가 완전히 눌러진 상태에서 발생
- 키 문자에 대한 정보를 사용할 수 있음
KeyUp
- 키를 떼었을 때 발생
- 키 상태와 보조키를 위한 Keys 열거형 정보를 사용할 수 있음
이벤트 발생순서
- KeyDown - KeyPress - KeyUp
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if(e.KeyChar == 13) // Enter값이 13이다.
{
button1_Click(sender, new EventArgs());
}
}
위와 같이 코드를 작성하면 Enter키를 눌렸을 때 인지를 하고 입력이 되는 코드입니다.
리스트 뷰
리스트 상자와 유사한 형태를 지니며 목록을 구조적으로 장식할 수 있는 컨트롤 (리스트상자 + 추가적인 정보)
리스트 뷰의 형태
- View 프로퍼티의 값에 따라 다양한 형태를 가짐
- System.Windows.Forms 네임스페이스에 포함된 View열거형을 값으로 가짐
SelectedItems 프로퍼티
- 리스트 뷰에서 선택된 항목을 저장하는 프로퍼티
- 반환형
- ListViewItem 클래스형 - 리스트 뷰의 MultiSelect 프로퍼티가 거짓일 경우
- ListViewItem 클래스의 배열형 - 리스트 뷰의 MultiSelect 프로퍼티가 참일 경우
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: //Tiles
listView1.View = View.Tile;
break;
default:
break;
}
}
private void listView1_SelectedIndexChanged(object sender, EventArgs e)
{
foreach (ListViewItem item in listView1.SelectedItems)
{
ListViewSubItemCollection subItem = item.SubItems; //alt+enter눌려서 using사용하기
label1.Text = $"{item.Text}의 국가번호는 {subItem[1].Text}";
}
}
트리 뷰
- 목록을 계층적으로 보여주기 위한 컨트롤
- 노드를 계층적으로 표시
- 노드에 이미지 아이콘을 추가할 수 있음
트리 뷰의 노드
- 트리 노드 편집기를 통해 생성
- TreeNode 클래스의 객체
- TreeView 컨트롤의 Nodes 프로퍼티에 TreeNodeCollection 형으로 저장
- TreeNodeCollection 클래스의 메소드를 통해 노드의 편집이 가능함
업다운 컨트롤
주어진 목록에서 항목을 선택할 수 있는 컨트롤
- 업다운 버튼을 이용하여 필요한 값을 선택
- 스핀 컨트롤(spin control)
영역 업다운 컨트롤
- 문자열로 이루어진 항목에서 특정한 항목을 선택할 수 있는 컨트롤
수치적 업다운 컨트롤
- 지정한 범위 내에서 수치적 값을 선택할 수 있는 컨트롤
간단한 트리뷰 예제를 만들어 보겠습니다.
선택될 때마다 모양이 바뀝니다.
자식 추가를 누른뒤 위와 같이 설정해주세요
노드 추가와 노드 삭제의 기능도 추가해주겠습니다.
private void Form1_Activated(object sender, EventArgs e)
{
treeView1.ExpandAll(); // 모든 자식 노드가 펼쳐진다.
treeView1.CollapseAll();// 모든 자식 노드를 닫는다
}
private void button1_Click(object sender, EventArgs e) // Add Node Button
{
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);
}
트랙 바
범위 내에서 값을 선택할 수 있는 컨트롤
슬라이더의 이동
- 마우스 드래그
- 슬라이더의 좌우 공간 클릭
- 마우스 휠의 회전
- 키보드의 좌우 방향키, 페이지 업다운키
트랙 바의 추가
[ 도구상자 - TrackBar ]를 선택하여 폼에 추가
트랙 바의 값에 대한 범위와 이동량을 설정
트랙바의 프로퍼티를 통해 설정
슬라이더 형태와 눈금이 표시되는 위치 설정
TickStyle 프로퍼티에 TickStyle 열거형 값을 배정하여 설정
프로그레스 바
작업의 진행상황을 보여주는 컨트롤
- 좌측에서 우측으로 사각형의 조각을 채우면서 진행
- 애플리케이션의 설치과정이나 파일 복사과정에서 사용
프로그레스 바의 추가
[ 도구상자 - ProgressBar ]를 선택하여 폼에 추가
프로그레스 바의 값에 대한 범위를 설정
프로그레스 바의 프로퍼티를 통해 설정 [ Maximun(최대값) / Minimum(최소값) ]
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < progressBar1.Maximum; i++)
{
progressBar1.Value = i;
}
}
progressBar1의 Maximum값에 저는 속성창에서 100,000이라는 값을 넣어 뒀습니다.
타이머
주기적인 간격으로 이벤트를 발생시키는 컴포넌트
- 배경작업을 처리할 때 주로 사용
- 일정한 간격에 따라 Tick 이벤트를 발생
- Interval 프로퍼티를 통해 간격을 설정
- 밀리 초(millisecond, 1/1000초)를 사용
- 주기적으로 발생시키기 위해서는 Enable 프로퍼티를 참으로 설정
- 항상 Interval 프로퍼티의 간격에 따라 Tick 이벤트가 발생하는 것은 아님
타이머 컴포넌트의 추가
[ 도구상자 - Timer ]를 선택하여 폼에 추가
timer의 interval값을 100으로 설정해줍니다.
이미지 크기와 비트 수준을 위와 같이 해주세요
그리고 모양이 다른 8개의 사진을 준비해주세요! imageList에 넣어주세요.
private void timer1_Tick(object sender, EventArgs e) //Tick안에는 반복문을 안 넣는다.
{
index %= imageList1.Images.Count;
label1.Image = imageList1.Images[index++];
}
private void Form1_Load(object sender, EventArgs e)
{
timer1.Enabled = true;
}
위의 이미지는 정지되어있지만 실행을 시키면 8개의 사진이 0.1초마다 바뀌면서 새가 날아가는 모습이 표현됩니다 :)
그리기 개요
Graphics(System.Drawing.Graphics) 클래스
- System.Drawing 네임페이스에 포함
- 선, 사각형, 타원 등과 같은 도형을 그리는데 필요한 기본적인 메소드들이 존재
그래픽 객체
- 도형을 그리기 위해 필요한 Graphics 클래스의 객체
- 그리기판이 되는 대상
- 객체를 얻거나 생성하는 방법
- Paint 이벤트 처리기의 매개변수
- Control 클래스의 CreateGraphics() 메소드
- Graphics.FromImage() 메소드
Paint 이벤트의 매개변수
- Paint 이벤트 : 폼을 다시 그려야 할 때 발생하는 이벤트
- 처리기의 두 번째 매개변수에 그래픽 객체가 들어 있음
- 여기에 그리기 작업을 하면 폼에 그려짐
Paint 이벤트 처리기의 메소드 형식
private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
Graphics g = e.Graphics;
//그래픽 객체를 이용한 그리기 작업
//...
}
CreateGraphics() 메소드
- Paint 이벤트 처리기가 아닌 다른 곳에서 그리기를 하고자 할 때 사용.
- 메소드를 사용하여 그래픽 객체를 생성
- Control 클래스의 메소드이기 때문에 파생된 모든 클래스에서 그래픽 객체를 만들 수 있음
사용 방법
private void DrawPrivateObject() {
//단계 1: 그래픽 객체를 생성
Graphics g = CreateGraphics();
//...
//단계 2: 그래픽 객체를 이용하여 그리기
//...
}
Graphics.FromImage() 메소드
- 이미지에서 만들어진 그래픽 객체이기 때문에 그리기 작업의 결과가 화면에 곧바로 나타나지 않음
- 결과를 화면에 표시하려면 이미지 객체를 화면에 출력해야 함
- 그리기 도중에 발생할 수 있는 깜박거림을 제거하기 위해 사용
사용 방법
private void DrawOffScreenImage() {
//단계 1: 이미지 객체로부터 그래픽 객체를 생성
Image img = new Bitmap(w, h);
Graphics bg = Graphics.FromImage(img);
//...
//단계 2: bg에 그리기 작업을 한다.
//...
//단계 3: 결과 이미지를 표시하기 위한 그래픽 객체를 생성
Graphics fg = CreateGraphics();
//...
//단계 4: 이미지를 화면에 출력
fg.DrawImage(img, 0, 0);
}
Point 구조체 - 평면상의 한 점을 표시하기 위한 자료형
// 생성자
Point pt = new Point(); // (0,0)을 나타냄.
Point pt = new Point(x,y); // (x,y)좌표를 나타냄.
Size 구조체 - 사각형 모양을 갖는 영역의 크기를 나타내기 위해서 사용되는 구조체
// 생성자
Size area = new Size();
Size area = new Size(Width, Height);
Rectangle 구조체 - 사각형 모양을 갖는 영역의 위치와 크기를 나타내기 위해서 사용
// 생성자
Rectangle r = new Rectangle();
Rectangle r = new Rectangle(Point, Size);
Rectangle r = new Rectangle(X, Y, Width, Height);
Color 구조체 - 색을 RGB(Red, Green, Blue) 형식으로 나타낸 구조체
// 생성자
Color c = Color.FromArgb(R, G, B);
Color c = Color.FromArgb(A, R, G, B); // A는 투명도 값
Color c = Color.FromKnownColor(KnownColor.Member);
Color c = Color.FromName("ColorName");
다양한 클래스도 많지만 스마트팩토리 과정에는 알맞지 않기 때문에 구조체까지만 포스팅 하겠습니다...!
'C# Winform' 카테고리의 다른 글
C# Winform 강의 6일차 (0) | 2020.06.22 |
---|---|
C# Winform 강의 5일차 (0) | 2020.06.19 |
C# Winform 강의 4일차 (0) | 2020.06.18 |
C# Winform 강의 2일차 (0) | 2020.06.16 |
C# Winform 강의 1일차 (0) | 2020.06.15 |