순서

I. Canvas. Childred. Add
II. Rendering
III. 기타 (DrawingContext, DrawingVisual)


I. 1. Canvas. Childred. Add

 

"Canvas에 그림을 그린다." 라고 했을 때 가장 쉬운 방법은 무엇일까?

Canvas의 자식객체로 추가하는 것이다.

Mainwindow.xaml
<grid>
  <Canvas x:Name = "mycanvas"/>
<grid>


Mainwindow.xaml.cs

using System.Windows.Shapes;
public partial class MainWindow : Window {

  public MainWindow() {

    InitializeComponent(); // 기본으로 있는 것
    Rectangle R = new Rectangle();
    R.Height = 100;
    R.Width = 100;
    mycanvas.Children.Add(R);
  }
}

아주 쉽다. 
Shape에서 사각형을 의미하는 Rectangle 객체를 선언해 mycanvas의 Children으로 추가한다.

하지만 이러면 그려지지 않는다.
단순히 그냥 객체 오브젝트를 canvas에 넣은 것 뿐이다.

그림 속성을 선언해주자.

Shape Class는 Drawing 속성도 같이 지원한다.

using System.Windows.Shapes;
using System.Windows.Media;

public partial class MainWindow : Window {

  public MainWindow() {

    InitializeComponent(); // 기본
    Rectangle R = new Rectangle();
    R.Height = 100;
    R.Width = 100;
    R.Fill = Brushes.Red; // 빨강으로 채우고
    R.Stroke = Brushes.Black; // 검정으로 선을 긋고
    R.StrokeThickness = 2; // 선의 두께는 2
    mycanvas.Children.Add(R);
  }
}

Windows.Media에 있는 Brushes를 사용하여 Fill과 Stroke를 지정해주고
Shape 객체 멤버로 있는 StrockThickness를 정의하였다.

결과

이게 Canvas에 그림을 그리는 가장 쉬운 방법이다.

하지만 이건 엄밀히 그리는 것이 아니라, 그림 속성이 있는
Shape 객체를 그냥 canvas의 멤버로 넣은 것 뿐이다.

 


I. 2. Rendering

 

두번째는 렌더링이다. 객체를 실제로 화면에 나타나게 하는 작업이 렌더링이라고 생각하자.

Canvas위에 Rendering을 할 것이기 때문에
Canvas를 상속받는 Class를 하나 만들어서 두가지 작업을 진행 할 것이다.

기억할 것!!

Canvas의 가상함수인 OnRender() 함수는 시스템에서 직접 자동으로 불러주는
렌더링 함수이다.

 

2-1. System이 자동으로 해주는 Rendering 확인

Mainwindow.xaml
<grid>
// 1. local:myRendering으로 변경
  <local:myRendering x:Name = "myRenderingcanvas"/>
<grid>

Mainwindow.xaml.cs

using System.Windows.Shapes;
using System.Windows.Media;
using System.Windows.Controls; // Canvas 객체를 사용하기 위함.

public partial class MainWindow : Window {

  public MainWindow() {
    InitializeComponent(); // 기본
    Rectangle R = new Rectangle();
    R.Height = 100;
    R.Width = 100;
    R.Fill = Brushes.Red;
    R.Stroke = Brushes.Black;
    R.StrokeThickness = 2;
    
    myRenderingcanvas.Children.Add(R);
  }
  // 2. 새로 만든 클래스
  public class myRendering : Canvas {
    protected override void OnRender(DrawingContext dc) {
      base.OnRender(dc);
    }
  }
}

1. xaml에서 Canvas 객체로 되어있는 부분을 내가 직접 만든 myRendering으로 변경하였다.
    Canvas를 상속 받았으므로 객체로 변경할 수 있다.

2. xaml.cs에서 override된 OnRender함수는 DrawingContext를 받아 OnRender를 진행한다.
    -> 현재는 구현부가 없어서 base. 함수가 불린다.(명시하려고 적어둠)

3. 그럼 결과로 mycanvas에 사각형이 추가가 되었고 동일하게 사각형이 나올 것이다.

=>  다만 System에서 자동으로 OnRender를 불러주는 것을 볼 수 있다.

사실 이 base.OnRender(dc)를 지워도 사각형이 그려진다.
그 말은 -> 렌더링을 하지 않은 것이다.

진짜 시스템에서 렌더링을 하기 위해서는
인자로 받은 DrawingContext에 그리기 Method를 사용해야한다.

 


2-2. 직접 Rendering

OnRender 함수 내부에서 Canvas가 제공하는 Draw~~~ 메소드를 사용해서
직접 구현해 볼 것이다.

첫째로 DrawingContext에는 아래와 같은 Method들이 존재한다.

Mainwindow.xaml
<grid>
  <local:myRendering/>
<grid>

Mainwindow.xaml.cs

using System.Windows.Shapes;
using System.Windows.Media;
using System.Windows.Controls; // Canvas 객체를 사용하기 위함.

public partial class MainWindow : Window {

  public MainWindow() {
    InitializeComponent(); // 기본
  }
  
  public class myRendering : Canvas {
    protected override void OnRender(DrawingContext dc) {
      Rect R = new Rect();
      R.Width = 100; // 가로길이
      R.Height = 100; //세로길이
      //사각형 좌측 모서리가 Canvas의 좌측부터 offset
      R.X = 10;
      // 사각형의 상단 모서리가 Canvas의 상단부터 offset
      R.Y = 10; // Canvas의 위부터 Y 만큼 아래로
      // Drawing 메소드 사용
      dc.DrawRectangle(Brushes.Black. new Pen(Brushes.Red,2), R)
    }
  }
}

1. xaml에서 canvas 이름도 삭제함
2. MainWindow 구현 삭제
3. 단지 OnRender만 구현
4. ★ OnRender는 시스템에서 알아서 호출해준다. 실행시 우선 바로 호출

이 과정에서 우리는 위와 다르게 "Rect" 를 사용하였다.

Shape에서 파생된 것이 아니라, 단순히 사각형을 설명하는 것이고,
OnRender에서 DrawRectangle을 통해 렌더링을 한 것이다.

 

그렇다면 결국
단순 도형설명 + Draw의 기능 = Shape Class라는 말이 된다.
그리고 이것은 MFC Windows개발이 아닌 WPF인 덕에 지원하는 것이다.

 


III. 기타 (DrawingContext, DrawingVisual)

 

저 DrawingContext는 뭔데 시스템에서 자동으로 호출하는 것일까?그리고 OnRender를 직접 호출하는 것도
DrawingContext 인자 때문에 불가능 해 보인다.

간단하게 파일 입출력이라고 생각해보자,
파일을 열고, 적고, 닫는다.
도화지도 똑같다.
도화지를 열고, 그리고, 닫는다.
다만 여기서
어떤 그림? = DrawingContext
도화지?     = DrawingVisual 이라고 생각하자.

즉, 아래 코드처럼 DrawingVisualRenderOpen()으로 열면 DrawingContext인 것이다.

DrawingVisual drawingVisual = new DrawingVisual;
DrawingContext drawingContext = drawingVisual.RenderOpen();

drawingContext.DrawRectangle(...);
drawingContext.Close();

하지만 닫을 때는, DrawingContext가 해준다. drawingContext.Close();

+ Recent posts