이번에는 캔버스를 이용하여 그림판처럼 선과 원, 네모 등을 그려볼 것이다.
전체 xaml코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | <Window x:Class="_0312.paint" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:_0312" mc:Ignorable="d" Title="paint" Height="600" Width="1000" MouseLeftButtonDown="canvas_MouseLeftButtonDown" MouseLeftButtonUp="canvas_MouseLeftButtonUp" MouseMove="canvas_MouseMove" MouseRightButtonDown="canvas_MouseRightButtonDown" MouseRightButtonUp="canvas_MouseRightButtonUp" > <Grid> <Border x:Name="canvasborder" BorderBrush="Pink" BorderThickness="3" CornerRadius="10" Margin="10,50,10,10"> <Canvas x:Name="canvas" HorizontalAlignment="Left" Height="489" Margin="7,7,0,0" VerticalAlignment="Top" Width="952"> </Canvas> </Border> <Button x:Name="button_line" Content="선" HorizontalAlignment="Left" Margin="15,7,0,0" VerticalAlignment="Top" Width="50" Height="35" Click="button_line_Click" /> <Button x:Name="button_circle" Content="원" HorizontalAlignment="Left" Margin="80,7,0,0" VerticalAlignment="Top" Width="50" Height="35" Click="button_circle_Click"/> <Button x:Name="button_rectangle" Content="네모" HorizontalAlignment="Left" Margin="145,7,0,0" VerticalAlignment="Top" Width="50" Height="35" Click="button_rectangle_Click"/> <Button x:Name="button_erase" Content="지우개" HorizontalAlignment="Left" Margin="210,7,0,0" VerticalAlignment="Top" Width="50" Height="35" Click="button_erase_Click"/> <Button x:Name="button_fileopen" Content="파일열기" HorizontalAlignment="Left" Margin="509,7,0,0" VerticalAlignment="Top" Width="50" Height="35" Click="button_fileopen_Click" /> <Button x:Name="button_jsonsave" Content="save" HorizontalAlignment="Left" Margin="739,7,0,0" VerticalAlignment="Top" Width="50" Height="35" Click="button_jsonsave_Click" /> <Button x:Name="button_jsonload" Content="load" HorizontalAlignment="Left" Margin="797,7,0,0" VerticalAlignment="Top" Width="50" Height="35" Click="button_jsonload_Click" /> <Button x:Name="button_paint" Content="배경색" HorizontalAlignment="Left" Margin="863,7,0,0" VerticalAlignment="Top" Width="50" Height="35" Click="button_paint_Click"/> <Button x:Name="button_allerase" Content="전체삭제" HorizontalAlignment="Left" Margin="923,7,0,0" VerticalAlignment="Top" Width="50" Height="35" Click="button_allerase_Click"/> <Button x:Name="color_black" Content=" " HorizontalAlignment="Left" Margin="337,13,0,0" VerticalAlignment="Top" Width="25" Height="25" BorderBrush="Black" Background="Black" Click="color_black_Click" /> <Button x:Name="color_red" Content=" " HorizontalAlignment="Left" Margin="369,13,0,0" VerticalAlignment="Top" Width="25" Height="25" BorderBrush="Black" Background="Red" Click="color_red_Click"/> <Button x:Name="color_blue" Content=" " HorizontalAlignment="Left" Margin="401,13,0,0" VerticalAlignment="Top" Width="25" Height="25" BorderBrush="Black" Background="Blue" Click="color_blue_Click"/> <Button x:Name="color_green" Content=" " HorizontalAlignment="Left" Margin="433,13,0,0" VerticalAlignment="Top" Width="25" Height="25" BorderBrush="Black" Background="green" Click="color_green_Click"/> <Button x:Name="color_yellow" Content=" " HorizontalAlignment="Left" Margin="465,13,0,0" VerticalAlignment="Top" Width="25" Height="25" BorderBrush="Black" Background="Yellow" Click="color_yellow_Click" /> <ComboBox x:Name="comboBox" HorizontalAlignment="Left" Margin="274,14,0,0" VerticalAlignment="Top" Width="50" SelectionChanged="comboBox_SelectionChanged"> <ComboBoxItem>10</ComboBoxItem> <ComboBoxItem IsSelected="True">20</ComboBoxItem> <ComboBoxItem>30</ComboBoxItem> </ComboBox> </Grid> </Window> | cs |
기본 자료는 여기를 참고 →
우선 선긋기부터.
캔버스를 하나 만들어준다. 그리고 마우스를 클릭하면 mClicked를 true로 바꾸고 현재위치를 prePosition에 넣는다.
1 2 3 4 5 | private void canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { mClicked = true; prePosition = e.GetPosition(canvas); } | cs |
그리고 마우스를 움직이면 새로운 위치를 받아 이전위치에서 현재위치까지의 선을 긋는다.
새로 그은 선을 캔버스의 자식으로 넣어주고 이전위치에 현재위치를 넣어준다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | private void canvas_MouseMove(object sender, MouseEventArgs e) { var nowPosition = e.GetPosition(canvas); if (mClicked) { // 선 if (lineClicked) { Line line = new Line(); line.X1 = prePosition.X; line.X2 = nowPosition.X; line.Y1 = prePosition.Y; line.Y2 = nowPosition.Y; line.Stroke = mycolor; line.StrokeThickness = 2; canvas.Children.Add(line); prePosition = nowPosition; } | cs |
이런 식으로 작은 무수히 많은 선들로 그림판의 펜 기능을 만들 수 있다.
다음은 사각형 그리기
사각형의 위치는 margin을 이용해 시작점을 잡고, width와 height로 크기를 조절한다.
예외로는 시작점보다 현재위치의 x값이나 y값이 더 뒤로가게되면 너비,높이에 -1을 곱해 양수로 만들어주고
여백을 현재 x,y값으로 바꾸어주어 뒤쪽 방향으로도 정상적으로 사각형이 출력되도록 만든다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | // 사각형그리기 if (rectangleClicked) { if (e.MouseDevice.LeftButton == MouseButtonState.Pressed) { Rectangle myrectangle = new Rectangle(); myrectangle.Stroke = Brushes.Plum; myrectangle.Fill = mycolor; myrectangle.Opacity = 0.8; double left = prePosition.X; double top = prePosition.Y; double width = nowPosition.X - prePosition.X; double height = nowPosition.Y - prePosition.Y; if (nowPosition.X < prePosition.X) { left = nowPosition.X; width *= -1; } if (nowPosition.Y < prePosition.Y) { top = nowPosition.Y; height *= -1; } myrectangle.Margin = new Thickness(left, top, 0, 0); myrectangle.Width = width; myrectangle.Height = height; canvas.Children.Remove(temprectangle); temprectangle = myrectangle; canvas.Children.Add(myrectangle); } else temprectangle = null; } | cs |
그리고 마우스를 이동할때마다 이전에 그렸던 사각형을 삭제하고 새로운 사각형을 생성함으로서
그림판처럼 생성될 사각형이 이동되는 것을 미리 확인 할 수있다. 마우스를 떼면 그자리에 그대로 사각형이 남는다.
지우개도 사각형과 같은 방식으로 색깔만 흰색으로 구현하였다.
다음은 원그리기
원도 사각형과 마찬가지이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | // 원그리기 if (circleClicked) { if (e.MouseDevice.LeftButton == MouseButtonState.Pressed) { Ellipse myellipse = new Ellipse(); myellipse.Fill = mycolor; myellipse.StrokeThickness = 2; myellipse.Stroke = Brushes.LightSkyBlue; myellipse.Opacity = 0.8; double width = nowPosition.X - prePosition.X; double height = nowPosition.Y - prePosition.Y; double left = prePosition.X; double top = prePosition.Y; if (nowPosition.X < prePosition.X) { left = nowPosition.X; width *= -1; } if (nowPosition.Y < prePosition.Y) { top = nowPosition.Y; height *= -1; } myellipse.Margin = new Thickness(left, top, 0, 0); myellipse.Width = width; myellipse.Height = height; canvas.Children.Remove(tempellipse); tempellipse = myellipse; canvas.Children.Add(myellipse); } else tempellipse = null; } | cs |
마우스를 떼면 변수와 나머지를 초기화해주어 동작을 하지않도록 한다.
1 2 3 4 5 6 | private void canvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { mClicked = false; temprectangle = null; tempellipse = null; } | cs |
이미지의 전체 삭제는 canvas.Children.Clear()를 하면 자식들이 전부 날아가서 캔버스가 초기화상태로 돌아간다.
배경화면도 투명으로 같이 초기화 해주었다.
1 2 3 4 5 | private void button_allerase_Click(object sender, RoutedEventArgs e) { canvas.Children.Clear(); canvas.Background = Brushes.Transparent; } | cs |
그 외 도형선택과 색상변경은 아래와 같이 노가다로 만들었다. (좋지못한 예)
1 2 3 4 5 6 7 8 9 | private void color_red_Click(object sender, RoutedEventArgs e) { mycolor = Brushes.Red; color_black.Opacity = 1.0; color_red.Opacity = 0.5; color_blue.Opacity = 1.0; color_green.Opacity = 1.0; color_yellow.Opacity = 1.0; } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 | private void button_line_Click(object sender, RoutedEventArgs e) { lineClicked = true; circleClicked = false; rectangleClicked = false; eraseClicked = false; button_line.BorderBrush = Brushes.Red; button_circle.BorderBrush = Brushes.Black; button_rectangle.BorderBrush = Brushes.Black; button_erase.BorderBrush = Brushes.Black; } | cs |
지우개 크기는 콤보박스를 이용해 사이즈를 조절해주었다.
1 2 3 4 | private void comboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { erasesize = (comboBox.SelectedIndex + 1) * 10; } | cs |
배경색도 그냥 캔버스의 Background를 바꾸면 끝이다.
1 2 3 4 5 | private void button_paint_Click(object sender, RoutedEventArgs e) { canvas.Background = mycolor; canvasborder.BorderBrush = Brushes.Pink; } | cs |
'프로그래밍 공부 > WPF' 카테고리의 다른 글
json 저장, 불러오기 (0) | 2018.04.02 |
---|---|
파일 불러오기, 이미지 출력 및 이동하기 (0) | 2018.04.02 |
음악 재생하기 (MediaPlayer 사용) (1) | 2018.04.02 |
계산기 만들기 (0) | 2018.04.02 |
WPF 시작하기 (0) | 2018.04.02 |