C#图形绘制工具介绍

在开发复杂的图形项目时,一个实用的起点是创建一个能够绘制矩形、圆形和其他形状的工具,同时还能移动、调整大小甚至旋转一些形状。本文将介绍一个基于C#的图形绘制工具,它不仅支持基本的绘图功能,还提供了丰富的属性设置和图形导出功能。

要完全理解这个代码,用户需要了解一些C#的基本概念,如反射接口继承等。此外,还有一个使用WPF技术的绘图工具版本,可以在找到。

使用代码

该项目首先创建了一个包含所有可用绘图工具的工具箱。用户可以选择这些工具在主屏幕上进行绘制。项目还提供了一个属性包,允许用户动态更改形状的边框颜色、填充颜色、箭头宽度、文本框内容、文本大小等。

用户完成绘图后,可以选择将绘图导出为XML文件或JPG文件。下面是一个XML文件的示例,展示了如何保存图形数据:

<?xml version="1.0" encoding="utf-8"?> <ShapeList xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <LeShape xsi:type="LeRectangle"> <ShowBorder>true</ShowBorder> <LeBorderColor> <A>255</A> <R>0</R> <G>0</G> <B>0</B> </LeBorderColor> <BorderWidth>1</BorderWidth> <Rect> <X>300</X> <Y>157</Y> <Width>79</Width> <Height>65</Height> </Rect> <LeFromColor> <A>30</A> <R>255</R> <G>0</G> <B>0</B> </LeFromColor> <LeToColor> <A>30</A> <R>255</R> <G>255</G> <B>255</B> </LeToColor> <LightAngle>225</LightAngle> <Fill>true</Fill> </LeShape> </ShapeList>

使用上述XML文件,项目可以在下次打开时加载这些文件,用户可以继续编辑他们的绘图。

项目解释

定义了几个基本形状,LeShape是基类。为了序列化形状,重新定义了LeColor结构,如下所示:

public struct LeColor { public int A; public int R; public int G; public int B; public LeColor(Color color) { this.A = color.A; this.R = color.R; this.G = color.G; this.B = color.B; } public static LeColor FromColor(Color color) { return new LeColor(color); } public Color ToColor() { return Color.FromArgb(A, R, G, B); } }

由于不能将C#的Font和Color类序列化为XML,创建了它们的等效结构并在所有地方使用它们。

public abstract class LeShape : IShape { private bool showBorder = true; public bool ShowBorder { get { return showBorder; } set { showBorder = value; LeCanvas.self.Canvas.Invalidate(); } } private LeColor borderColor = new LeColor(Color.Black); public LeColor LeBorderColor { get { return borderColor; } set { borderColor = value; LeCanvas.self.Canvas.Invalidate(); } } [XmlIgnore] public Color BorderColor { get { return LeBorderColor.ToColor(); } set { LeBorderColor = new LeColor(value); } } private int borderWidth = 1; public int BorderWidth { get { return borderWidth; } set { borderWidth = value; LeCanvas.self.Canvas.Invalidate(); } } private Rectangle bounds; [XmlIgnore] public Rectangle Boundary { set { bounds = value; Rect = new LeRect(value); } get { return bounds; } } // 更多代码... }

LeShape类是一个抽象类,因为不希望用户在任何时候实例化它。相反,创建了ZoneShape、Rectangle等形状类,然后实例化它们,这样更有意义。

为了让用户能够移动和调整形状的大小,创建了另一个类BoundaryShape,它继承自LeShape,包含所有属性,而这个BoundaryShape只处理用户的鼠标移动,并且不会被序列化为XML文件。基本上所有形状都将从BoundaryShape继承,而BoundaryShape继承自LeShape。

public class RoundRectShape : BoundaryShape { private int radius = 10; // 可以有圆角形状,默认半径为10像素。 public override void Paint(object sender, Graphics g) { Point[] pt = new Point[8]; // 绘制圆角矩形形状的代码... } }

这个Paint方法在BoundaryShape中有副本,不想使用它,所以用override作为修饰符。

ZoneShape有一个文本字段,当ZoneShape移动时,文本字段也会随之移动。这是通过在用户完成移动ZoneShape后,在BoundaryShape中引发事件,ZoneShape接受这个事件然后处理这个事件,移动文本字段参数来实现的。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485