본문으로 바로가기

C# Winform 강의 3일차

category C# Winform 2020. 6. 17. 18:26

안녕하세요 문쑹입니다 :)

오늘도 열심히 포스팅을 해보겠습니다!

 

메뉴 다루기

메뉴

윈폼 애플리케이션에서 가장 일반적인 사용자 인터페이스

윈폼 애플리케이션이 제공하는 기능을 사용자가 쉽게 이해하고 사용할 수 있도록 도와주는 기능

 

메뉴의 종류

메인 메뉴 (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();
            }
        }

contextMenu 실행 화면

마우스

윈도우 사용자에게 가장 편리하고 친숙한 입력장치

윈폼 애플리케이션의 사용자 상호작용은 대부분 마우스를 통해 이루어진다.

사용자가 마우스를 이동하거나 클릭하면 이벤트가 발생

 

마우스 이벤트

이동 이벤트 - 사용자가 마우스의 위치를 이동시킬 경우 발생

선택 이벤트 - 사용자가 마우스의 버튼을 클릭할 경우 발생

 

마우스 이동 이벤트

 

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 열거형 값을 배정하여 설정

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 클래스의 객체

 - 그리기판이 되는 대상

 - 객체를 얻거나 생성하는 방법

  1. Paint 이벤트 처리기의 매개변수
  2. Control 클래스의 CreateGraphics() 메소드
  3. 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