728x90
반응형
728x170
■ PathGeometry 클래스를 사용해 GraphicsPath 객체에서 패스 지오메트리 객체를 구하는 방법을 보여준다.
▶ MainWindow.xaml
<Window x:Class="TestProject.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="800"
Height="600"
Title="PathGeometry 클래스 : GraphicsPath 객체에서 패스 지오메트리 구하기"
FontFamily="나눔고딕코딩"
FontSize="16">
<Grid>
<Path Name="path"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Stroke="Red"
StrokeThickness="3">
</Path>
</Grid>
</Window>
▶ MainWindow.xaml.cs
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows;
using System.Windows.Media;
namespace TestProject
{
/// <summary>
/// 메인 윈도우
/// </summary>
public partial class MainWindow : Window
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - MainWindow()
/// <summary>
/// 생성자
/// </summary>
public MainWindow()
{
InitializeComponent();
GraphicsPath graphicsPath = GetRoundedRectanglePath(new RectangleF(0, 0, 300, 300), 10, 10, true, true, true, true);
PathGeometry pathGeometry = GetPathGeometry(graphicsPath);
this.path.Data = pathGeometry;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Private
#region 라운드 사각형 패스 구하기 - GetRoundedRectanglePath(rectangle, radiusX, radiusY, roundUpperLeft, roundUpperRight, roundLowerRight, roundLowerLeft)
/// <summary>
/// 라운드 사각형 패스 구하기
/// </summary>
/// <param name="rectangle">사각형</param>
/// <param name="radiusX">반경 X</param>
/// <param name="radiusY">반경 Y</param>
/// <param name="roundUpperLeft">좌상단 라운드 여부</param>
/// <param name="roundUpperRight">우상단 라운드 여부</param>
/// <param name="roundLowerRight">우하단 라운드 여부</param>
/// <param name="roundLowerLeft">좌하단 라운드 여부</param>
/// <returns>라운드 사각형 패스</returns>
private GraphicsPath GetRoundedRectanglePath
(
RectangleF rectangle,
float radiusX,
float radiusY,
bool roundUpperLeft,
bool roundUpperRight,
bool roundLowerRight,
bool roundLowerLeft
)
{
PointF point1;
PointF point2;
GraphicsPath path = new GraphicsPath();
if(roundUpperLeft)
{
RectangleF cornerRectangle = new RectangleF
(
rectangle.X,
rectangle.Y,
2 * radiusX,
2 * radiusY
);
path.AddArc(cornerRectangle, 180, 90);
point1 = new PointF(rectangle.X + radiusX, rectangle.Y);
}
else
{
point1 = new PointF(rectangle.X, rectangle.Y);
}
if(roundUpperRight)
{
point2 = new PointF(rectangle.Right - radiusX, rectangle.Y);
}
else
{
point2 = new PointF(rectangle.Right, rectangle.Y);
}
path.AddLine(point1, point2);
if(roundUpperRight)
{
RectangleF cornerRectangle = new RectangleF
(
rectangle.Right - 2 * radiusX,
rectangle.Y,
2 * radiusX,
2 * radiusY
);
path.AddArc(cornerRectangle, 270, 90);
point1 = new PointF(rectangle.Right, rectangle.Y + radiusY);
}
else
{
point1 = new PointF(rectangle.Right, rectangle.Y);
}
if(roundLowerRight)
{
point2 = new PointF(rectangle.Right, rectangle.Bottom - radiusY);
}
else
{
point2 = new PointF(rectangle.Right, rectangle.Bottom);
}
path.AddLine(point1, point2);
if(roundLowerRight)
{
RectangleF cornerRectangle = new RectangleF
(
rectangle.Right - 2 * radiusX,
rectangle.Bottom - 2 * radiusY,
2 * radiusX,
2 * radiusY
);
path.AddArc(cornerRectangle, 0, 90);
point1 = new PointF(rectangle.Right - radiusX, rectangle.Bottom);
}
else
{
point1 = new PointF(rectangle.Right, rectangle.Bottom);
}
if(roundLowerLeft)
{
point2 = new PointF(rectangle.X + radiusX, rectangle.Bottom);
}
else
{
point2 = new PointF(rectangle.X, rectangle.Bottom);
}
path.AddLine(point1, point2);
if(roundLowerLeft)
{
RectangleF cornerRectangle = new RectangleF
(
rectangle.X,
rectangle.Bottom - 2 * radiusY,
2 * radiusX,
2 * radiusY
);
path.AddArc(cornerRectangle, 90, 90);
point1 = new PointF(rectangle.X, rectangle.Bottom - radiusY);
}
else
{
point1 = new PointF(rectangle.X, rectangle.Bottom);
}
if(roundUpperLeft)
{
point2 = new PointF(rectangle.X, rectangle.Y + radiusY);
}
else
{
point2 = new PointF(rectangle.X, rectangle.Y);
}
path.AddLine(point1, point2);
path.CloseFigure();
return path;
}
#endregion
#region 패스 지오메트리 구하기 - GetPathGeometry(graphicsPath)
/// <summary>
/// 패스 지오메트리 구하기
/// </summary>
/// <param name="graphicsPath">그래픽스 패스</param>
/// <returns>패스 지오메트리</returns>
private PathGeometry GetPathGeometry(GraphicsPath graphicsPath)
{
List<PathFigure> pathFigureList = new List<PathFigure>();
if(graphicsPath.PointCount != 0)
{
PointF[] pathPointArray = graphicsPath.PathPoints;
byte[] pathTypeByteArray = graphicsPath.PathTypes;
PathFigure pathFigure = new PathFigure();
pathFigureList.Add(pathFigure);
int index = 0;
while(index < pathPointArray.Length)
{
switch((int)pathTypeByteArray[index] & 7)
{
case 0 :
System.Windows.Point point1 = new System.Windows.Point
(
(double)pathPointArray[index].X,
(double)pathPointArray[index].Y
);
pathFigure.StartPoint = point1;
++index;
break;
case 1 :
System.Windows.Point point2 = new System.Windows.Point
(
(double)pathPointArray[index].X,
(double)pathPointArray[index].Y
);
pathFigure.Segments.Add((PathSegment)new LineSegment(point2, true));
++index;
break;
case 3 :
System.Windows.Point point3 = new System.Windows.Point
(
(double)pathPointArray[index].X,
(double)pathPointArray[index].Y
);
System.Windows.Point point4 = new System.Windows.Point
(
(double)pathPointArray[index + 1].X,
(double)pathPointArray[index + 1].Y
);
System.Windows.Point point5 = new System.Windows.Point
(
(double)pathPointArray[index + 2].X,
(double)pathPointArray[index + 2].Y
);
pathFigure.Segments.Add((PathSegment)new BezierSegment(point3, point4, point5, true));
index += 3;
break;
}
if(((int)pathTypeByteArray[index - 1] & 128) != 0)
{
pathFigure.IsClosed = true;
pathFigure = new PathFigure();
pathFigureList.Add(pathFigure);
}
}
}
return new PathGeometry((IEnumerable<PathFigure>)pathFigureList)
{
FillRule = graphicsPath.FillMode == FillMode.Alternate ? FillRule.EvenOdd : FillRule.Nonzero
};
}
#endregion
}
}
728x90
반응형
그리드형(광고전용)
'C# > WPF' 카테고리의 다른 글
[C#/WPF] ResourceDictionary 클래스 : MergedDictionaries 속성을 사용해 Application 객체의 리소스 사용하기 (0) | 2021.07.08 |
---|---|
[C#/WPF] ControlTemplate 엘리먼트 : Thumb/ScrollBar/ListBoxItem 엘리먼트 정의하기 (0) | 2021.06.07 |
[C#/WPF] HwndSource 클래스 : FromHwnd 정적 메소드를 사용해 윈도우 핸들로 윈도우 구하기 (0) | 2021.06.07 |
[C#/WPF] 잠금 화면 설정하기 (기능 개선) (0) | 2021.05.31 |
[C#/WPF] 비동기 가상화 컬렉션 사용하기 (0) | 2021.05.21 |
[C#/WPF] 누겟 설치 : AvalonEdit (0) | 2021.05.10 |
[C#/WPF] 코드 편집기(Code Editor) 사용하기 (0) | 2021.05.07 |
[C#/WPF] Dispatcher 클래스 : DisableProcessing 메소드를 사용해 디스패처 비활성하기 (0) | 2021.05.01 |
[C#/WPF] Dispatcher 클래스 : PushFrame 메소드를 사용해 UI 업데이트 하기 (0) | 2021.04.30 |
[C#/WPF] Dispatcher 클래스 : BeginInvoke 메소드 사용하기 (0) | 2021.04.30 |
댓글을 달아 주세요