从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 = ;
  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. DrawingLine(new Point(, ), new Point(, ));
  35. DrawingLine(new Point(, ), new Point(, ));
  36. }
  37.  
  38. protected void DrawingLine(Point startPt, Point endPt)
  39. {
  40. LineGeometry myLineGeometry = new LineGeometry();
  41. myLineGeometry.StartPoint = startPt;
  42. myLineGeometry.EndPoint = endPt;
  43.  
  44. Path myPath = new Path();
  45. myPath.Stroke = Brushes.Black;
  46. myPath.StrokeThickness = ;
  47. myPath.Data = myLineGeometry;
  48.  
  49. canvas1.Children.Add(myPath);
  50. }
  51.  
  52. private void canvas1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
  53. {
  54. startMovePosition = e.GetPosition((Canvas)sender);
  55. isMoving = true;
  56. }
  57.  
  58. private void canvas1_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
  59. {
  60. isMoving = false;
  61. Point endMovePosition = e.GetPosition((Canvas)sender);
  62.  
  63. //为了避免跳跃式的变换,单次有效变化 累加入 totalTranslate中。
  64. totalTranslate.X += (endMovePosition.X - startMovePosition.X)/scaleLevel;
  65. totalTranslate.Y += (endMovePosition.Y - startMovePosition.Y)/scaleLevel;
  66. }
  67.  
  68. private void canvas1_MouseMove(object sender, MouseEventArgs e)
  69. {
  70. if (isMoving)
  71. {
  72. Point currentMousePosition = e.GetPosition((Canvas)sender);//当前鼠标位置
  73.  
  74. Point deltaPt = new Point(, );
  75. deltaPt.X = (currentMousePosition.X - startMovePosition.X) /scaleLevel;
  76. deltaPt.Y = (currentMousePosition.Y - startMovePosition.Y) /scaleLevel;
  77.  
  78. tempTranslate.X = totalTranslate.X + deltaPt.X;
  79. tempTranslate.Y = totalTranslate.Y + deltaPt.Y;
  80.  
  81. adjustGraph();
  82. }
  83. }
  84.  
  85. private void canvas1_MouseWheel(object sender, MouseWheelEventArgs e)
  86. {
  87. Point scaleCenter = e.GetPosition((Canvas)sender);
  88.  
  89. if (e.Delta > )
  90. {
  91. scaleLevel *= 1.08;
  92. }
  93. else
  94. {
  95. scaleLevel /= 1.08;
  96. }
  97. //Console.WriteLine("scaleLevel: {0}", scaleLevel);
  98.  
  99. totalScale.ScaleX = scaleLevel;
  100. totalScale.ScaleY = scaleLevel;
  101. totalScale.CenterX = scaleCenter.X;
  102. totalScale.CenterY = scaleCenter.Y;
  103.  
  104. adjustGraph();
  105. }
  106.  
  107. private void adjustGraph()
  108. {
  109. TransformGroup tfGroup = new TransformGroup();
  110. tfGroup.Children.Add(tempTranslate);
  111. tfGroup.Children.Add(totalScale);
  112.  
  113. foreach (UIElement ue in canvas1.Children)
  114. {
  115. ue.RenderTransform = tfGroup;
  116. }
  117. }
  118.  
  119. }
  120. }

变量说明:

  1.      //移动标志
  2. bool isMoving = false;
  3. //鼠标按下去的位置
  4. Point startMovePosition;
  5.  
  6. TranslateTransform totalTranslate = new TranslateTransform();//多次操作中需要对总的移动量进行统计。
  7. ScaleTransform totalScale = new ScaleTransform();//缩放变量
  8. Double scaleLevel = 1;//缩放的级别
  9.  
  10. 函数功能说明:
    DrawingLine 在指定的Canvas控件中画线,用于测试。
  1. 鼠标按下时,记录起始移动的位置点,标记拖动操作开始 isMoving = true
    鼠标移动过程中,将有效的移动距离记录到总移动变量 totalTranslate 当中,并对位置进行刷新。
    鼠标滚轮变化时,根据滚轮方向调整缩放级别。
    不同缩放级别下,屏幕中移动相同的距离,对于Canvs内的图形来说距离不同,因此需要对鼠标移动的距离进行修正,即将移动距离除以缩放级别,这样可以得到相对精确的移动位置。
  2.  
  3. 遗留问题:
    1、连续在不同位置进行缩放时,仍会有较小的抖动,细节处理上还有瑕疵。
    2、使用下面的语句,可以实现canvas1自动缩放(将canvas1的宽度与高度设为Auto)。
    canvas1.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
    canvas1.VerticalAlignment = System.Windows.VerticalAlignment.Stretch;
  4.  
  5. 学习太辛苦,采购点东西鼓励一下自己,微信扫描二维码,“香雪杂货店”欢迎您的到来,遇到喜欢的东西尽管带走~~

WPF 中Canvas图形移动、缩放代码的更多相关文章

  1. WPF中任意Object的XAML代码格式化输出

    原文:WPF中任意Object的XAML代码格式化输出 有时候,我们需要将WPF中的控件自身的XAML代码输出成文本,那么,我们可以使用System.Windows.Markup.XamlWriter ...

  2. WPF中,怎样将XAML代码加载为相应的对象?

    原文:WPF中,怎样将XAML代码加载为相应的对象? 在前面"在WPF中,如何得到任何Object对象的XAML代码?"一文中,我介绍了使用System.Windows.Marku ...

  3. 去除WPF中3D图形的锯齿

    原文:去除WPF中3D图形的锯齿 理论上讲PC在计算3D图形的时候是无法避免不出现锯齿的,因为3D图形都是又若干个三角形组成,如果3D图形想平滑就必须建立多个三角形,你可以想象一下正5边形和正100边 ...

  4. WPF中Canvas使用

    首先知道Canvas有Left.Right.Top和Bottom这四个属性,放入Canvas的元素通过这四个属性来决定它们在Canvas里面的位置. 比如: Xaml: <Canvas Hori ...

  5. WPF中图形表示语法详解(Path之Data属性语法)ZZ

    大可山 [MSN:a3news(AT)hotmail.com] http://www.zpxp.com 萝卜鼠在线图形图像处理 ------------------------------------ ...

  6. WPF中图形表示语法详解(Path之Data属性语法)

    原文 http://blog.csdn.net/johnsuna/article/details/1885597 老规矩,看图说话. 先看显示效果:(图1) XAML(代码A):<Page xm ...

  7. WPF中C#代码触发鼠标点击事件

    1.如下代码; <Button x:Name="btnTest" Click="btnTest_Click"> <Button.Trigger ...

  8. 在WPF中绘制多维数据集

    原文 https://stuff.seans.com/2008/08/13/drawing-a-cube-in-wpf/ 是时候使用WPF绘制一个简单的3D对象了.作为WPF中3D图形的快速介绍,让我 ...

  9. WPF中的数据绑定!!!

    引用自:https://msdn.microsoft.com/zh-cn/magazine/cc163299.aspx  数据点: WPF 中的数据绑定 数据点 WPF 中的数据绑定 John Pap ...

随机推荐

  1. 一个DELPHI操作USB摄像头类

    最近在使用Usb摄像头做了个项目,其中写了一个操作usb摄像头类分享给大家 {*******************************************************} { } ...

  2. DELPHI微信支付代码

    DELPHI微信支付代码   不管是微信支付还是支付宝支付, 3个最棘手的问题是:1,如何生成签名2,支付请求如何提交3, 如何验证签名 下面就围绕这二个问题来讲. 我使用的是XE3. 先看微信支付: ...

  3. (zxing.net)二维码Aztec的简介、实现与解码

    一.简介 Aztec Code是1995年,由Hand HeldProducts公司的Dr. Andrew Longacre设计.它是一种高容量的二维条形码格式.它可以对ASCII和扩展ASCII码进 ...

  4. node.js实现WebSocket

    最近在学习“HTML5游戏开发实战”,其中第8章内容是使用WebSocket来构建多人游戏---<你画我猜>.然而在实现过程中,却一直出错: 客户端请求时,服务器端会报错并终止: 而浏览器 ...

  5. 【062新题】OCP 12c 062出现大量新题-15

    choose one In your Oracle 12c database, you plan to execute the command: SQL> CREATE TABLESPACE t ...

  6. DZY Loves Math(莫比乌斯反演)

    \(x=p_1^{\alpha_1}p_2^{\alpha_2}...p_c^{\alpha_c}\) \(f(x)=\max(\alpha_1,\alpha_2,...,\alpha_c)\) \( ...

  7. [转载]java开发中的23种设计模式

    原文链接:http://blog.csdn.net/zhangerqing 设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反 ...

  8. C#6.0语言规范(六) 转换

    转换能够被视为是一个特定类型的表达式.转换可能会导致给定类型的表达式被视为具有不同的类型,或者它可能导致没有类型的表达式获取类型.转换可以是隐式或显式的,这决定了是否需要显式转换.例如,从类型int到 ...

  9. sublime text3: markdown 安装及常用语法简介

    自己上传到 github 上的 README.rdm 文件内容显示没有“美化”,所有内容都挤在一块儿了,很不舒服. 原因是:github 的文档 README.rdm 文件使用 markdown 编辑 ...

  10. 关于UUID

    UUID是通用唯一识别码的缩写,其目的,是让分布式系统中的所有元素,都能有唯一的辨识信息. UUID是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的. 在做后台管理的时候,经常会碰 ...