0. 前言

项目上需要绘制坐标轨迹,找开源组件也是费尽周折,最后发现Canvas + Polyline就可以基本的轨迹功能。为使轨迹不过于单调增加了网格线背景。

学习WPF: 第6个月。

1. 实现原理

网格线的绘制主要依赖窗口的宽高和设定的间隔计算,画多少行,画多少列,画多长,画多高。
支持窗口缩放只要是监听 SizeChanged 的回调事件,窗口尺寸变化,实现重绘和更新。

2. View代码

<Grid>
        <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. 效果演示