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 ...
随机推荐
- Swift3 页面顶部实现拉伸效果代码
//懒加载 //顶部需要拉伸自定义视图 lazy var headView:MyHeaderView = { //let hframe = CGRect(x: 0, y: 0, width: swid ...
- day09_雷神_模块二
day09 序列化之json 之前我们学习过用eval内置方法可以将一个字符串转成python对象,不过,eval方法是有局限性的,对于普通的数据类型,json.loads和eval都能用,但遇到特殊 ...
- CUDA cufftPlanMany的用法_31通道32*8像素的FFT
#include <cufft.h> #include <iostream> #include <cuda_runtime.h> #include <help ...
- [jquery]如何实现页面单块DIV区域滚动展示
// 未实现功能的代码 1(自己写的代码) var _cur_top = $(window).scrollTop(); var num = $(".class_section"). ...
- POJ 2570 线段树
Potted Flower Time Limit: 2000 MS Memory Limit: 65536 KB 64-bit integer IO format: %I64d , %I64u Jav ...
- Android-Java多线程通讯(生产者 消费者)&等待唤醒机制
多线程通讯:例如:有一个线程任务在run生产,还有一个线程任务在run消费: VIP尊贵的身份,生产者 消费者 方式,(精心生产制作一个超级无敌好吃的面包,卖给VIP尊贵的身份消费者)生产与消费 一对 ...
- ios 百度地图,火星坐标,地球坐标互转
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 3 ...
- GitHub 教程【转】
@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/c ...
- MySQL 并行复制(MTS) 从库更新的记录不存在实际却存在
目录 背景 版本 分析 测试 背景 开了并行复制的半同步从库SQL 线程报1032错误,异步复制从库没有报错,偶尔会出现这种 版本 mysql 5.7.16 redhat 6.8 mysql> ...
- while循环中使用scanf函数
妈的,这scanf函数学了快10年了,怎么还会出现莫名其妙的问题?看下面的代码(VS2012环境下运行): #define _CRT_SECURE_NO_WARNINGS #include<st ...

