[WPF로 도형그리기] 4. 도형 모델의 이해(C) - 원, 네모, 텍스트
2025. 3. 10. 21:57ㆍC#,WPF
이어서 원, 네모, 텍스트를 그려보겠습니다.
먼저 EllipseModel과 RectanlgeModel입니다.
// RectangleModel.cs
public class RectangleModel : ShapeBase
{
protected override Geometry CreateGeometry()
{
return new RectangleGeometry(new Rect(StartPoint, EndPoint));
}
}
// EllipseModel.cs
public class EllipseModel : ShapeBase
{
protected override Geometry CreateGeometry()
{
return new EllipseGeometry(new Rect(StartPoint, EndPoint));
}
}
두 모델 모두 바로 Rect와 Ellipse 클래스를 반환하는 것이 아닌 Geometry로 감싸서 반환하는 Rect나 Ellipse 클래스만으로 WPF 앱에서 그리기에 충분하지 못하기 때문입니다.
다음은 TextAnnotation 입니다. 이 도형의 경우 '네모 + 텍스트박스' 조합으로 구성됩니다. 해당 클래스의 코드 전체 입니다. 이어서 부분별로 살펴보겠습니다.
public class TextAnnotation : ShapeBase
{
private TextBox _textBox;
private const int TextBoxMargin = 5;
public TextAnnotation()
{
_textBox = new TextBox
{
Text = "RIVMT",
Foreground = Brushes.Red,
FontSize = 20,
FontWeight = FontWeights.Bold,
TextWrapping = TextWrapping.Wrap,
BorderBrush = Brushes.Transparent,
BorderThickness = new Thickness(0)
};
Loaded += (s, e) => AttachTextBox();
LayoutUpdated += (s, e) => UpdateTextBoxPosition();
}
private void AttachTextBox()
{
Canvas cnvDrawing = VisualTreeHelper.GetParent(this) as Canvas;
if (!cnvDrawing.Children.Contains(_textBox))
{
cnvDrawing.Children.Add(_textBox);
UpdateTextBoxPosition();
}
}
private void UpdateTextBoxPosition()
{
if (_textBox != null)
{
double x = Math.Min(StartPoint.X, EndPoint.X);
double y = Math.Min(StartPoint.Y, EndPoint.Y);
_textBox.Margin = new Thickness(x + TextBoxMargin, y + TextBoxMargin, TextBoxMargin, TextBoxMargin);
}
}
protected override Geometry CreateGeometry()
{
double width = Math.Max(0, Math.Abs(EndPoint.X - StartPoint.X));
double height = Math.Max(0, Math.Abs(EndPoint.Y - StartPoint.Y));
var geometry = new RectangleGeometry(new Rect(StartPoint, EndPoint));
return new RectangleGeometry(new Rect(StartPoint, EndPoint));
}
}
public TextAnnotation()
{
_textBox = new TextBox
{
Text = "RIVMT",
Foreground = Brushes.Red,
FontSize = 20,
FontWeight = FontWeights.Bold,
TextWrapping = TextWrapping.Wrap,
BorderBrush = Brushes.Transparent,
BorderThickness = new Thickness(0)
};
Loaded += (s, e) => AttachTextBox();
LayoutUpdated += (s, e) => UpdateTextBoxPosition();
}
생성자에서 TextBox 생성을합니다. 파워포인트의 텍스트 상자와 비슷한 기능을 구현하기 위해 TextWrapping 처리하였고, 텍스트 영역에 Bodrder는 제거하였습니다. 이어서 해당 UI Element가 로드될 때, 레이아웃이 변경될 때 이벤트핸들러를 추가했습니다.
private void AttachTextBox()
{
Canvas cnvDrawing = VisualTreeHelper.GetParent(this) as Canvas;
if (!cnvDrawing.Children.Contains(_textBox))
{
cnvDrawing.Children.Add(_textBox);
UpdateTextBoxPosition();
}
}
private void UpdateTextBoxPosition()
{
if (_textBox != null)
{
double x = Math.Min(StartPoint.X, EndPoint.X);
double y = Math.Min(StartPoint.Y, EndPoint.Y);
_textBox.Margin = new Thickness(x + TextBoxMargin, y + TextBoxMargin, TextBoxMargin, TextBoxMargin);
}
}
Canvas를 얻어와 TextBox를 추가하고 위치를 정해줍니다. TextBox의 Margin 속성이 없다면 텍스트 박스와 네모가 겹쳐져 원하는 기능을 구현할 수 없습니다.
'C#,WPF' 카테고리의 다른 글
[WPF로 도형그리기] 5. 프로젝트 마무리 (0) | 2025.03.18 |
---|---|
[WPF로 도형그리기] 3. 도형 모델의 이해(B) - 화살표, 자 (0) | 2025.03.07 |
[WPF로 도형그리기] 2. 도형 모델의 이해(A) (0) | 2025.03.04 |
[WPF로 도형그리기] 1. 기본 환경설정 및 UI 구성 (0) | 2025.02.28 |
[C#, WPF] 각도기 클래스 만들고 이를 이용하여 각도기 그리기(3) (0) | 2024.10.15 |