WPF 中Canvas图形移动、缩放代码
从Flash转C#,很多内容一知半解,边摸索边前进,代码粗糙,权当留个脚印。
只是想得到一个基础的移动和缩放功能的界面,找了很久都是画线、画矩形等基础形状的代码,移动和缩放说的并不清晰,只能自己努力来解决一下。
素材准备:
WPF项目的屏幕上放一个Canvas控件,名称为canvas1。
代码如下:
- using System;
- using System.Windows;
- using System.Windows.Media;
- using System.Windows.Input;
- using System.Windows.Shapes;
- using System.Windows.Controls;
- namespace WpfcanvasDrawing
- {
- /// <summary>
- /// MainWindow.xaml 的交互逻辑
- /// </summary>
- public partial class MainWindow : Window
- {
- //移动标志
- bool isMoving = false;
- //鼠标按下去的位置
- Point startMovePosition;
- TranslateTransform totalTranslate = new TranslateTransform();
- TranslateTransform tempTranslate = new TranslateTransform();
- ScaleTransform totalScale = new ScaleTransform();
- Double scaleLevel = ;
- public MainWindow()
- {
- InitializeComponent();
- canvas1.Focusable = true;//重要:默认条件下不接收鼠标事件
- canvas1.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
- canvas1.VerticalAlignment = System.Windows.VerticalAlignment.Stretch;
- canvas1.Background = Brushes.Transparent;//.Cyan;
- DrawingLine(new Point(, ), new Point(, ));
- DrawingLine(new Point(, ), new Point(, ));
- }
- protected void DrawingLine(Point startPt, Point endPt)
- {
- LineGeometry myLineGeometry = new LineGeometry();
- myLineGeometry.StartPoint = startPt;
- myLineGeometry.EndPoint = endPt;
- Path myPath = new Path();
- myPath.Stroke = Brushes.Black;
- myPath.StrokeThickness = ;
- myPath.Data = myLineGeometry;
- canvas1.Children.Add(myPath);
- }
- private void canvas1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
- {
- startMovePosition = e.GetPosition((Canvas)sender);
- isMoving = true;
- }
- private void canvas1_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
- {
- isMoving = false;
- Point endMovePosition = e.GetPosition((Canvas)sender);
- //为了避免跳跃式的变换,单次有效变化 累加入 totalTranslate中。
- totalTranslate.X += (endMovePosition.X - startMovePosition.X)/scaleLevel;
- totalTranslate.Y += (endMovePosition.Y - startMovePosition.Y)/scaleLevel;
- }
- private void canvas1_MouseMove(object sender, MouseEventArgs e)
- {
- if (isMoving)
- {
- Point currentMousePosition = e.GetPosition((Canvas)sender);//当前鼠标位置
- Point deltaPt = new Point(, );
- 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;
- adjustGraph();
- }
- }
- private void canvas1_MouseWheel(object sender, MouseWheelEventArgs e)
- {
- Point scaleCenter = e.GetPosition((Canvas)sender);
- if (e.Delta > )
- {
- scaleLevel *= 1.08;
- }
- else
- {
- scaleLevel /= 1.08;
- }
- //Console.WriteLine("scaleLevel: {0}", scaleLevel);
- totalScale.ScaleX = scaleLevel;
- totalScale.ScaleY = scaleLevel;
- totalScale.CenterX = scaleCenter.X;
- totalScale.CenterY = scaleCenter.Y;
- adjustGraph();
- }
- private void adjustGraph()
- {
- TransformGroup tfGroup = new TransformGroup();
- tfGroup.Children.Add(tempTranslate);
- tfGroup.Children.Add(totalScale);
- foreach (UIElement ue in canvas1.Children)
- {
- ue.RenderTransform = tfGroup;
- }
- }
- }
- }
变量说明:
- //移动标志
- 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;- 学习太辛苦,采购点东西鼓励一下自己,微信扫描二维码,“香雪杂货店”欢迎您的到来,遇到喜欢的东西尽管带走~~
WPF 中Canvas图形移动、缩放代码的更多相关文章
- WPF中任意Object的XAML代码格式化输出
原文:WPF中任意Object的XAML代码格式化输出 有时候,我们需要将WPF中的控件自身的XAML代码输出成文本,那么,我们可以使用System.Windows.Markup.XamlWriter ...
- WPF中,怎样将XAML代码加载为相应的对象?
原文:WPF中,怎样将XAML代码加载为相应的对象? 在前面"在WPF中,如何得到任何Object对象的XAML代码?"一文中,我介绍了使用System.Windows.Marku ...
- 去除WPF中3D图形的锯齿
原文:去除WPF中3D图形的锯齿 理论上讲PC在计算3D图形的时候是无法避免不出现锯齿的,因为3D图形都是又若干个三角形组成,如果3D图形想平滑就必须建立多个三角形,你可以想象一下正5边形和正100边 ...
- WPF中Canvas使用
首先知道Canvas有Left.Right.Top和Bottom这四个属性,放入Canvas的元素通过这四个属性来决定它们在Canvas里面的位置. 比如: Xaml: <Canvas Hori ...
- WPF中图形表示语法详解(Path之Data属性语法)ZZ
大可山 [MSN:a3news(AT)hotmail.com] http://www.zpxp.com 萝卜鼠在线图形图像处理 ------------------------------------ ...
- WPF中图形表示语法详解(Path之Data属性语法)
原文 http://blog.csdn.net/johnsuna/article/details/1885597 老规矩,看图说话. 先看显示效果:(图1) XAML(代码A):<Page xm ...
- WPF中C#代码触发鼠标点击事件
1.如下代码; <Button x:Name="btnTest" Click="btnTest_Click"> <Button.Trigger ...
- 在WPF中绘制多维数据集
原文 https://stuff.seans.com/2008/08/13/drawing-a-cube-in-wpf/ 是时候使用WPF绘制一个简单的3D对象了.作为WPF中3D图形的快速介绍,让我 ...
- WPF中的数据绑定!!!
引用自:https://msdn.microsoft.com/zh-cn/magazine/cc163299.aspx 数据点: WPF 中的数据绑定 数据点 WPF 中的数据绑定 John Pap ...
随机推荐
- 一个DELPHI操作USB摄像头类
最近在使用Usb摄像头做了个项目,其中写了一个操作usb摄像头类分享给大家 {*******************************************************} { } ...
- DELPHI微信支付代码
DELPHI微信支付代码 不管是微信支付还是支付宝支付, 3个最棘手的问题是:1,如何生成签名2,支付请求如何提交3, 如何验证签名 下面就围绕这二个问题来讲. 我使用的是XE3. 先看微信支付: ...
- (zxing.net)二维码Aztec的简介、实现与解码
一.简介 Aztec Code是1995年,由Hand HeldProducts公司的Dr. Andrew Longacre设计.它是一种高容量的二维条形码格式.它可以对ASCII和扩展ASCII码进 ...
- node.js实现WebSocket
最近在学习“HTML5游戏开发实战”,其中第8章内容是使用WebSocket来构建多人游戏---<你画我猜>.然而在实现过程中,却一直出错: 客户端请求时,服务器端会报错并终止: 而浏览器 ...
- 【062新题】OCP 12c 062出现大量新题-15
choose one In your Oracle 12c database, you plan to execute the command: SQL> CREATE TABLESPACE t ...
- 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)\) \( ...
- [转载]java开发中的23种设计模式
原文链接:http://blog.csdn.net/zhangerqing 设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反 ...
- C#6.0语言规范(六) 转换
转换能够被视为是一个特定类型的表达式.转换可能会导致给定类型的表达式被视为具有不同的类型,或者它可能导致没有类型的表达式获取类型.转换可以是隐式或显式的,这决定了是否需要显式转换.例如,从类型int到 ...
- sublime text3: markdown 安装及常用语法简介
自己上传到 github 上的 README.rdm 文件内容显示没有“美化”,所有内容都挤在一块儿了,很不舒服. 原因是:github 的文档 README.rdm 文件使用 markdown 编辑 ...
- 关于UUID
UUID是通用唯一识别码的缩写,其目的,是让分布式系统中的所有元素,都能有唯一的辨识信息. UUID是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的. 在做后台管理的时候,经常会碰 ...