Canvas绘图需手动创建Shape对象并添加到Children中;Line用X1/Y1和X2/Y2定义端点,设Stroke和StrokeThickness才可见;Ellipse/Rectangle用Canvas.SetLeft/SetTop定位;Path通过Geometry描述复杂形状;动态绘图需注意复用、Loaded事件及命中测试。

Canvas 绘图不是靠“绑定数据”或“触发事件”自动出来的,而是你主动创建 Shape 对象(比如 Line、Ellipse、Rectangle、Path),设置坐标和样式,再手动加进 Canvas.Children 里。不写代码,XAML 里静态放几个控件,根本算不上“绘图”。
怎么在 Canvas 上画一条线(Line)
最基础的绘图操作,但容易错在坐标理解、笔触不可见、或没加进容器。
-
Line没有Fill属性,必须设Stroke和StrokeThickness,否则什么也看不到 - X1/Y1 是起点,X2/Y2 是终点——它们是相对于
Line自身坐标系的,不是 Canvas 坐标;所以通常不需要设Canvas.Left/Canvas.Top - 如果你把
Line放在 Canvas 里又额外设置了Canvas.Left="100",那整条线会整体右移 100 像素,起点和终点都偏移 - 示例代码(后台):
var line = new Line { X1 = 20, Y1 = 30, X2 = 150, Y2 = 80, Stroke = Brushes.Blue, StrokeThickness = 2 }; canvas.Children.Add(line);
怎么画圆、矩形、椭圆(Ellipse/Rectangle)
这些是 Shape,默认以左上角为原点定位,所以要用 Canvas.SetLeft 和 Canvas.SetTop 控制位置,而不是直接设 Margin 或用 Canvas.Left 这类附加属性(后者对 Shape 无效)。
-
Ellipse和Rectangle的宽高由Width/Height决定,中心点位置 =Canvas.Left + Width/2、Canvas.Top + Height/2 - 想画“居中于某点 (cx, cy) 的圆”,别硬算 left/top,直接:
var circle = new Ellipse { Width = 40, Height = 40, Fill = Brushes.Red }; Canvas.SetLeft(circle, cx - 20); Canvas.SetTop(circle, cy - 20); canvas.Children.Add(circle); - 如果只设
Width没设Height,Ellipse会塌成一条水平线(高度为 0)
怎么画复杂路径(Path)和缺口圆
当你要画弧、贝塞尔曲线、带缺口的圆、箭头、不规则多边形时,Path 是唯一选择。它靠 Geometry 描述形状,不是靠宽高坐标。
- 不能直接给
Path.Data赋字符串,得转成Geometry:var path = new Path(); path.Data = Geometry.Parse("M 10,10 A 50,50 0 0 1 110,10"); // 圆弧 path.Stroke = Brushes.Black; path.StrokeThickness = 1.5; canvas.Children.Add(path); - 角度单位是弧度,不是度;
Math.PI / 180是常用转换因子 - 缺口圆本质是
A(Arc)指令,需计算起始/终止点坐标,还要注意IsLargeArc和SweepDirection参数,设反了弧就朝反方向弯 -
Path本身没有位置属性,它的位置由其Geometry决定;若要整体平移,得改Geometry.Transform或用Canvas.SetLeft/Canvas.SetTop移动整个Path元素
动态绘图时最容易被忽略的三件事
Canvas 不是 InkCanvas,它不会自动缓存、重绘或响应鼠标拖拽。所有“动态”逻辑都得你亲手控制。
- 频繁增删
Children会导致 UI 卡顿,尤其上百个图形时;优先考虑复用对象(如移动Canvas.SetLeft而非反复Add/Remove) -
Canvas.ActualWidth和ActualHeight在控件未加载完成前是 0,用它们算坐标一定会出错;务必监听Loaded或SizeChanged事件后再初始化绘图 - Canvas 不处理 Z 轴点击穿透,如果多个
Shape重叠,上层元素会拦截鼠标事件;需要交互时,要么设IsHitTestVisible="False"让点击透下去,要么手动遍历Children做命中测试











