为建立中文知识库加块砖 ——中科大胡不归
0. 前言
项目上需要绘制坐标轨迹,找开源组件也是费尽周折,最后发现Canvas + Polyline就可以基本的轨迹功能。为使轨迹不过于单调增加了网格线背景。
学习WPF: 第6个月。
1. 实现原理
网格线的绘制主要依赖窗口的宽高和设定的间隔计算,画多少行,画多少列,画多长,画多高。
支持窗口缩放只要是监听 SizeChanged 的回调事件,窗口尺寸变化,实现重绘和更新。2. View代码
<Canvas x:Name="MyGrid"> </Canvas> <WrapPanel VerticalAlignment="Bottom" HorizontalAlignment="Center"> <Button Click="ButtonPath_OnClick">左手轨迹</Button> <Button Click="ButtonDrawCircle_OnClick">右手画圆</Button> </WrapPanel> </Grid>3. 后端代码
namespace DrawGrid public partial class MainWindow public MainWindow() InitializeComponent(); InitData(); SizeChanged += MainWindow_Resize; private void MainWindow_Resize(object sender, EventArgs e) MyGrid.Children.Clear(); GridTool.Draw(MyGrid); DrawPath(MyGrid); private readonly Polyline _line = new Polyline(); private readonly PointCollection _collection = new PointCollection(); private readonly Random _random = new Random(); private void ButtonPath_OnClick(object sender, RoutedEventArgs e) _collection.Add(new Point(_random.Next(1, (int)ActualWidth),_random.Next(1, (int)ActualHeight))); MyGrid.Children.Clear(); GridTool.Draw(MyGrid); DrawPath(MyGrid); private void DrawPath(Panel panel) _line.Points = _collection; _line.Stroke = new SolidColorBrush(Colors.Black); _line.StrokeThickness = 1; panel.Children.Add(_line); private void ButtonDrawCircle_OnClick(object sender, RoutedEventArgs e) MyGrid.Children.Clear(); GridTool.DrawCircle(MyGrid); private void InitData() _collection.Add(new Point(20,20)); _collection.Add(new Point(40,25)); _collection.Add(new Point(60,40)); _collection.Add(new Point(80,120)); _collection.Add(new Point(120,140)); _collection.Add(new Point(200,180));
4. DrawGrid代码
public static void Draw(Canvas canvas) var gridBrush = new SolidColorBrush {Color = Colors.Red}; double scaleX = 30; double currentPosY = 0; currentPosY += scaleX; while (currentPosY < canvas.ActualHeight) Line line = new Line X1 = 0, Y1 = currentPosY, X2 = canvas.ActualWidth, Y2 = currentPosY, Stroke = gridBrush, StrokeThickness = 0.1 canvas.Children.Add(line); currentPosY += scaleX; double scaleY = 30; double currentPosX = 0; currentPosX += scaleY; while (currentPosX < canvas.ActualWidth) Line line = new Line X1 = currentPosX, Y1 = 0, X2 = currentPosX, Y2 = canvas.ActualHeight, Stroke = gridBrush, StrokeThickness = 0.1 canvas.Children.Add(line); currentPosX += scaleY;
封装成工具类,源码 。
5. 效果演示