之前一直用GDI繪圖,後面公司要求使用WPF,網上WPF資料太少(可能自己沒找到吧),自己寫了個測試用,可以拖動。 前端代碼 後臺代碼 ...
之前一直用GDI繪圖,後面公司要求使用WPF,網上WPF資料太少(可能自己沒找到吧),自己寫了個測試用,可以拖動。
前端代碼
<Window x:Class="Wpf繪圖.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="600" Width="800" Loaded="Window_Loaded_1"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="30"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <ToolBar Grid.Row="0"> <Label Name="moushPonit" Foreground="Red">11</Label> </ToolBar> <Canvas Grid.Row="1" Name="MainCanvas" Background="#FFBBBCBF" MouseMove="MainCanvas_MouseMove" MouseLeftButtonDown="MainCanvas_MouseLeftButtonDown" MouseLeftButtonUp="MainCanvas_MouseLeftButtonUp" SizeChanged="MainCanvas_SizeChanged" ClipToBounds="True"> <Canvas.RenderTransform> <TransformGroup> <ScaleTransform x:Name="sfr" /> <TranslateTransform x:Name="tlt" /> </TransformGroup> </Canvas.RenderTransform> </Canvas> </Grid> </Window>
後臺代碼
using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Shapes; namespace Wpf繪圖 { /// <summary> /// Window1.xaml 的交互邏輯 /// </summary> public partial class Window1 : Window { /// <summary> /// 畫板寬度 /// </summary> double BoardWidth { get; set; } /// <summary> /// 畫板高度 /// </summary> double BoardHeight { get; set; } /// <summary> /// 垂直(縱向)邊距(畫圖區域距離左右兩邊長度) /// </summary> double VerticalMargin { get; set; } /// <summary> /// 平行(橫向)邊距(畫圖區域距離左右兩邊長度) /// </summary> double HorizontalMargin { get; set; } /// <summary> /// 水平刻度間距像素 /// </summary> double horizontalBetween { get; set; } /// <summary> /// 垂直刻度間距像素 /// </summary> double verticalBetween { get; set; } /// <summary> /// x軸最大值 /// </summary> public double MaxX { get; set; } /// <summary> /// y軸最大值 /// </summary> public double MaxY { get; set; } /// <summary> /// x軸最小值 /// </summary> public double MinX { get; set; } /// <summary> /// y軸最小值 /// </summary> public double MinY { get; set; } /// <summary> /// 圖表區域寬度 /// </summary> double ChartWidth; /// <summary> /// 圖表區域高度 /// </summary> double CharHeight; /// <summary> /// 畫圖區域起點 /// </summary> Point StartPostion; /// <summary> /// 畫圖區域終點 /// </summary> Point EndPostion; /// <summary> /// 數據源 /// </summary> PointCollection DataSourse; double MapLocationX = 0; double MapLocationY = 0; //滑鼠按下去的位置 Point startMovePosition; TranslateTransform totalTranslate = new TranslateTransform(); TranslateTransform tempTranslate = new TranslateTransform(); ScaleTransform totalScale = new ScaleTransform(); Double scaleLevel = 1; public Window1() { InitializeComponent(); DataSourse = GetCollPoint(); } private void MainCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { startMovePosition = e.GetPosition((Canvas)sender); } private void MainCanvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { /* Point endMovePosition = e.GetPosition((Canvas)sender); totalTranslate.X += (endMovePosition.X - startMovePosition.X) / scaleLevel; totalTranslate.Y += (endMovePosition.Y - startMovePosition.Y) / scaleLevel; */ } private void MainCanvas_MouseMove(object sender, MouseEventArgs e) { Point currentMousePosition = e.GetPosition((UIElement)sender); moushPonit.Content = currentMousePosition.X.ToString() + "," + currentMousePosition.Y.ToString(); if (e.LeftButton == MouseButtonState.Pressed) { MapLocationX = MapLocationX + currentMousePosition.X - startMovePosition.X; MapLocationY = MapLocationY + currentMousePosition.Y - startMovePosition.Y; startMovePosition = currentMousePosition; Refresh(); /* Point deltaPt = new Point(0, 0); deltaPt.X = (currentMousePosition.X - startMovePosition.X) / scaleLevel; deltaPt.Y = (currentMousePosition.Y - startMovePosition.Y) / scaleLevel; tempTranslate.X = totalTranslate.X + deltaPt.X; tempTranslate.Y = totalTranslate.Y + deltaPt.Y; TransformGroup tfGroup = new TransformGroup(); tfGroup.Children.Add(tempTranslate); tfGroup.Children.Add(totalScale); foreach (UIElement ue in MainCanvas.Children) { ue.RenderTransform = tfGroup; }*/ } } private void MainCanvas_SizeChanged(object sender, SizeChangedEventArgs e) { Refresh(); } private void Refresh() { InitCanvas(); //獲取y最大值 if (MaxY < 0.0001) { MaxY = DataSourse.Max(m => m.Y); } //MinY = DataSourse.Min(m => m.Y); if (MaxX < 0.0001) { MaxX = DataSourse.Max(m => m.X); } //MinX = DataSourse.Min(m => m.X); if (Math.Abs(MaxX) < 0.000001 || Math.Abs(MaxY) < 0.000001) { return; } DrawAxis(); DrawXAxisTicks(); DrawYAxisTicks(); DrawPolyline(); } private void InitCanvas() { MainCanvas.Children.Clear(); BoardWidth = MainCanvas.ActualWidth - SystemParameters.VerticalScrollBarWidth; BoardHeight = MainCanvas.ActualHeight - SystemParameters.HorizontalScrollBarHeight; HorizontalMargin = 40; VerticalMargin = 40; //horizontalBetween = 50; //verticalBetween = 50; ChartWidth = BoardWidth - 2 * HorizontalMargin;//畫圖區域寬度 CharHeight = BoardHeight - 2 * VerticalMargin; //畫圖區域高度 StartPostion = new Point(HorizontalMargin, VerticalMargin); EndPostion = new Point(BoardWidth - HorizontalMargin, BoardHeight - VerticalMargin); } private void DrawPolyline() { var polyline = new Polyline(); foreach (var t in DataSourse) { polyline.Points.Add(GetRealPoint(t)); } polyline.Stroke = Brushes.Blue; MainCanvas.Children.Add(polyline); } private Point GetRealPoint(Point point) { var realX = StartPostion.X + (point.X - MinX) * ChartWidth / (MaxX - MinX) + MapLocationX; var realY = StartPostion.Y + (MaxY - point.Y) * CharHeight / (MaxY - MinY) + MapLocationY; return new Point(realX, realY); } /// <summary> /// 畫y軸刻度 /// </summary> private void DrawYAxisTicks() { if (MinY >= MaxY) { return; } if (verticalBetween < 0.0001) { verticalBetween = (MaxY - MinY) / 10; } for (var i = MinY; i <= MaxY + 0.01; i += verticalBetween) { var y = EndPostion.Y - i * CharHeight / (MaxY - MinY) + MapLocationY; var marker = new Line { X1 = StartPostion.X - 5, Y1 = y, X2 = StartPostion.X, Y2 = y, Stroke = Brushes.Red }; MainCanvas.Children.Add(marker); //畫y軸字元 var markText = new TextBlock { Text = i.ToString(CultureInfo.InvariantCulture), Width = 30, Foreground = Brushes.Yellow, FontSize = 10, HorizontalAlignment = HorizontalAlignment.Right, TextAlignment = TextAlignment.Right }; MainCanvas.Children.Add(markText); Canvas.SetTop(markText, y - 10); Canvas.SetLeft(markText, 00); } } /// <summary> /// 畫x軸標簽 /// </summary> private void DrawXAxisTicks() { if (MinX >= MaxX) { return; } if (horizontalBetween < 0.0001) { horizontalBetween = (MaxX - MinX) / 10; } for (var i = MinX; i <= MaxX + 0.01; i += horizontalBetween) { var x = StartPostion.X + i * ChartWidth / (MaxX - MinX) + MapLocationX; var marker = new Line { X1 = x, Y1 = EndPostion.Y, X2 = x, Y2 = EndPostion.Y+4, Stroke = Brushes.Red }; MainCanvas.Children.Add(marker); var gridLine = new Line { X1 = x, Y1 = StartPostion.Y, X2 = x, Y2 = EndPostion.Y, StrokeThickness = 1, Stroke = new SolidColorBrush(Colors.AliceBlue) }; MainCanvas.Children.Add(gridLine); //畫x軸字元 var text = i.ToString(CultureInfo.InvariantCulture); var markText = new TextBlock { Text = text, Width = 130, Foreground = Brushes.Yellow, VerticalAlignment = VerticalAlignment.Top, HorizontalAlignment = HorizontalAlignment.Stretch, TextAlignment = TextAlignment.Left, FontSize = 15 }; //Transform st = new SkewTransform(0, 0); //markText.RenderTransform = st; MainCanvas.Children.Add(markText); Canvas.SetTop(markText, EndPostion.Y + 5); Canvas.SetLeft(markText, x); } } /// <summary> /// X軸Y軸 /// </summary> private void DrawAxis() { var xaxis = new Line { X1 = StartPostion.X, Y1 = EndPostion.Y, X2 = EndPostion.X, Y2 = EndPostion.Y, Stroke = new SolidColorBrush(Colors.Black) }; MainCanvas.Children.Add(xaxis); var yaxis = new Line { X1 = StartPostion.X, Y1 = StartPostion.Y, X2 = StartPostion.X, Y2 = EndPostion.Y, Stroke = new SolidColorBrush(Colors.Black) }; MainCanvas.Children.Add(yaxis); } /// <summary> /// 獲取數據源 /// </summary> /// <returns></returns> private PointCollection GetCollPoint() { PointCollection myPointCollection = new PointCollection() { new Point(1,12), new Point(2,20), new Point(3,50), new Point(4,21), new Point(6,10), new Point(21,90) }; return myPointCollection; } private void Window_Loaded_1(object sender, RoutedEventArgs e) { } } }