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

