IT/C#

[C#] 윈도우 그림판 만들기 심화편 (Struct 구조체 이용하기 + List<Struct> 사용방법)

Ella.J 2023. 4. 7. 17:38
728x90
반응형

 

이전 포스팅 보러 가기.

2020.10.16 - [IT/C#] - [C#] 윈도우 그림판 기능 구현해보기 (PictureBox 그리기 기능, Undo/Redo 기능, 단축키 사용 방법)

 

[C#] 윈도우 그림판 기능 구현해보기 (PictureBox 그리기 기능, Undo/Redo 기능, 단축키 사용 방법)

그림판에 여러 기능들 중에서 크게 두 가지 기능을 구현해보겠습니다. 1. 도형(사각형, 원형, 선형직선) 그리기 기능과 2. 실행 취소(Undo)/다시 실행(Redo) 기능 두 가지 입니다. 그리고 흔히들 사용

ella-devblog.tistory.com

2023.04.07 - [IT/C#] - [C#] 윈도우 그림판 만들기 3탄(?) 테이블 그리기 (PictureBox Draw Table with Col, Row)

 

[C#] 윈도우 그림판 만들기 3탄(?) 테이블 그리기 (PictureBox Draw Table with Col, Row)

2020.10.16 - [IT/C#] - [C#] 윈도우 그림판 기능 구현해보기 (PictureBox 그리기 기능, Undo/Redo 기능, 단축키 사용 방법) [C#] 윈도우 그림판 기능 구현해보기 (PictureBox 그리기 기능, Undo/Redo 기능, 단축키 사용

ella-devblog.tistory.com

 

 

그림판을 이용할 때 Undo/Redo 실행취소/되돌리기 기능을 이용하기 위해 그림정보를 저장해야 할 필요가 있습니다.

이전 포스팅에서는 Rectangle은 Rectangle끼리 List를 만들고, PaintTool은 PaintTool끼리 List를 만들었습니다.

근데, 나는 각각의 그림에 Pen 색상도, 라인 굵기도 지정하고 싶고, 표도 그리고 싶다 하면,

이런 정보들을 다 한꺼번에 관리하기 위해 Struct 구조체를 사용합니다.

구조체를 잘 만들면 유지보수도 용이하고, 확장성도 좋기 때문에 잘 알아두면 좋습니다.

 

이렇게 그려도 Undo/Redo 했을 때 동일한 색상, 동일한 굵기 해당 도형으로 정상적으로 그릴 수 있습니다.

 

 

 

 

전체적인 소스코드를 첨부하는 것은 아니지만 Struct 사용방법에 대해서만 간략하게 설명해 보겠습니다.

 

이전 포스팅에 보면 이렇게 PaintTools enum이 있고, 4개의 List로 그림 정보를 저장했습니다.

근데 여기서 추가로 저장하고 싶은 게 있으면 List가 계속 늘어나고 코드가 끝도 없이 길어집니다.

그래서 저는 구조체를 이렇게 만들었습니다.

기존의 Rectangle과 PaintTools에 이어 표 그리기 포스팅에서 사용할 Col/Row 데이터와, 그림을 그릴 때의 Pen Color, Line굵기 정보를 같이 저장하도록 했습니다.

 

이렇게 되면 DrawInfo 구조체에 모든 정보들이 들어가고, 현재 정보 list와 실행취소 시에 사용할 temp 딱 두 개의 List로 관리할 수 있습니다.

 

PenTools 구조체도 선언하여, Pen Color와 Line 굵기를 관리할 수 있도록 했습니다.

 

 

만약, 사용자가 그림판 툴, 예를 들면 Rectangle을 선택하고, 빨간색의 3p 크기의 펜으로 그렸으면,

MouseUp 이벤트에서 드래그가 끝났을 때(=그림을 그렸을 때) listInfo에 저장해 주면 됩니다.

 

listInfo에 그림 정보를 넣는 코드이고, 중단점을 잡고 확인해 본 데이터입니다.

구조체에 값을 할당하는 방법은 위 코드처럼 두 가지가 있습니다.

1. PenTools처럼 새로운 구조체 변수를 선언하고 pen.penColor 처럼 .(점)을 이용해 해당 필드에 값을 넣는 방법이 있고,

2. DrawInfo처럼 {} 괄호를 이용하여 괄호 안에서 바로 필드에 접근하여 rectInfo = rect 와 같이 사용하는 방법이 있습니다.

 

그러면 Undo/Redo 사용 시에도 간단하게 listInfo와 tempInfo 두 가지로만 관리할 수 있습니다.

 

그리고 사용하실 때는 이렇게 구조체변수에서 각 필드값을 호출할 수 있습니다.

 

 

중요

그리고, 만약 List 0번째의 필드값을 바꾸고 싶다?

이렇게 코드를 작성하면 위와 같이 이렇게 직접 할당할 수 없다는 에러가 나옵니다.

Cannot modify the return value of 'List<Form1.DrawInfo>.this[int]' because it is not a variable

왜냐, 간단하게 얘기하면 Get만 되고 Set은 안되기 때문입니다.

 

그러면 어떻게 하냐,

요렇게 임시로 구조체를 변수 temp를 하나 만들고, listInfo[0] 값을 넣어주고,

temp.rectInfo 값을 바꿔준 다음에 listInfo[0]에다가 temp를 넣어줘야 합니다.

그러면 정상적으로 해당값이 변경됩니다.

 

 

설명이 충분했는지 모르겠네요.. 하하

궁금하신 점 언제든지 댓글 남겨주시고, 조금이라도 도움이 되셨으면, 공감❤ 버튼 꾹! 눌러주세요😊

그럼 이만!!🖐

 

728x90
반응형