WPF 中Canvas圖形移動、縮放代碼


從Flash轉C#,很多內容一知半解,邊摸索邊前進,代碼粗糙,權當留個腳印。

只是想得到一個基礎的移動和縮放功能的界面,找了很久都是畫線、畫矩形等基礎形狀的代碼,移動和縮放說的並不清晰,只能自己努力來解決一下。

素材准備:

WPF項目的屏幕上放一個Canvas控件,名稱為canvas1。

代碼如下:

 

  1 using System;
  2 using System.Windows;
  3 using System.Windows.Media;
  4 using System.Windows.Input;
  5 using System.Windows.Shapes;
  6 using System.Windows.Controls;
  7 
  8 namespace WpfcanvasDrawing
  9 {
 10     /// <summary>
 11     /// MainWindow.xaml 的交互邏輯
 12     /// </summary>
 13     public partial class MainWindow : Window
 14     {
 15         //移動標志
 16         bool isMoving = false;
 17         //鼠標按下去的位置
 18         Point startMovePosition;
 19 
 20         TranslateTransform totalTranslate = new TranslateTransform();
 21         TranslateTransform tempTranslate = new TranslateTransform();
 22         ScaleTransform totalScale = new ScaleTransform();
 23         Double scaleLevel = 1;
 24 
 25         public MainWindow()
 26         {
 27             InitializeComponent();
 28 
 29             canvas1.Focusable = true;//重要:默認條件下不接收鼠標事件
 30             canvas1.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
 31             canvas1.VerticalAlignment = System.Windows.VerticalAlignment.Stretch;
 32             canvas1.Background = Brushes.Transparent;//.Cyan;
 33 
 34 
 35             DrawingLine(new Point(100, 100), new Point(300, 200));
 36             DrawingLine(new Point(100, 200), new Point(300, 100));
 37         }
 38 
 39         protected void DrawingLine(Point startPt, Point endPt)
 40         {
 41             LineGeometry myLineGeometry = new LineGeometry();
 42             myLineGeometry.StartPoint = startPt;
 43             myLineGeometry.EndPoint = endPt;
 44 
 45             Path myPath = new Path();
 46             myPath.Stroke = Brushes.Black;
 47             myPath.StrokeThickness = 1;
 48             myPath.Data = myLineGeometry;
 49 
 50             canvas1.Children.Add(myPath);
 51         }
 52 
 53         private void canvas1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
 54         {           
 55             startMovePosition = e.GetPosition((Canvas)sender);
 56             isMoving = true;
 57         }
 58 
 59         private void canvas1_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
 60         {
 61             isMoving = false;
 62             Point endMovePosition = e.GetPosition((Canvas)sender);
 63 
 64             //為了避免跳躍式的變換,單次有效變化 累加入 totalTranslate中。           
 65             totalTranslate.X += (endMovePosition.X - startMovePosition.X)/scaleLevel;
 66             totalTranslate.Y += (endMovePosition.Y - startMovePosition.Y)/scaleLevel;           
 67         }
 68 
 69         private void canvas1_MouseMove(object sender, MouseEventArgs e)
 70         {
 71             if (isMoving)
 72             {
 73                 Point currentMousePosition = e.GetPosition((Canvas)sender);//當前鼠標位置
 74                 
 75                 Point deltaPt = new Point(0, 0);               
 76                 deltaPt.X = (currentMousePosition.X - startMovePosition.X) /scaleLevel;                
 77                 deltaPt.Y = (currentMousePosition.Y - startMovePosition.Y) /scaleLevel;
 78                 
 79                 tempTranslate.X = totalTranslate.X + deltaPt.X;
 80                 tempTranslate.Y = totalTranslate.Y + deltaPt.Y;
 81 
 82                 adjustGraph();
 83             }
 84         }        
 85         
 86         private void canvas1_MouseWheel(object sender, MouseWheelEventArgs e)
 87         {
 88             Point scaleCenter = e.GetPosition((Canvas)sender);
 89 
 90             if (e.Delta > 0)
 91             {
 92                 scaleLevel *= 1.08;
 93             }
 94             else
 95             {
 96                 scaleLevel /= 1.08;
 97             }
 98             //Console.WriteLine("scaleLevel: {0}", scaleLevel);
 99 
100             totalScale.ScaleX = scaleLevel;
101             totalScale.ScaleY = scaleLevel;
102             totalScale.CenterX = scaleCenter.X;
103             totalScale.CenterY = scaleCenter.Y;
104 
105             adjustGraph();
106         }
107        
108         private void adjustGraph()
109         {
110             TransformGroup tfGroup = new TransformGroup();
111             tfGroup.Children.Add(tempTranslate);
112             tfGroup.Children.Add(totalScale);
113 
114             foreach (UIElement ue in canvas1.Children)
115             {
116                 ue.RenderTransform = tfGroup;
117             }
118         }
119 
120     }
121 }

 

變量說明:

     //移動標志 bool isMoving = false; //鼠標按下去的位置  Point startMovePosition; TranslateTransform totalTranslate = new TranslateTransform();//多次操作中需要對總的移動量進行統計。  ScaleTransform totalScale = new ScaleTransform();//縮放變量 Double scaleLevel = 1;//縮放的級別

函數功能說明:
DrawingLine 在指定的Canvas控件中畫線,用於測試。
鼠標按下時,記錄起始移動的位置點,標記拖動操作開始 isMoving = true。
鼠標移動過程中,將有效的移動距離記錄到總移動變量 totalTranslate 當中,並對位置進行刷新
鼠標滾輪變化時,根據滾輪方向調整
縮放級別。

不同縮放級別下,屏幕中移動相同的距離,對於Canvs內的圖形來說距離不同,因此需要對鼠標移動的距離進行修正,即將移動距離除以縮放級別,這樣可以得到相對精確的移動位置。

遺留問題:
1、連續在不同位置進行縮放時,仍會有較小的抖動,細節處理上還有瑕疵。
2、使用下面的語句,可以實現canvas1自動縮放(將canvas1的寬度與高度設為Auto)。
canvas1.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
canvas1.VerticalAlignment = System.Windows.VerticalAlignment.Stretch;



學習太辛苦,采購點東西鼓勵一下自己,微信掃描二維碼,“香雪雜貨店”歡迎您的到來,遇到喜歡的東西盡管帶走~~



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM