从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图形移动、缩放代码的更多相关文章

  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. EBS Custom Password Rules

    https://blogs.oracle.com/manojmadhusoodanan/entry/custom_password_rules Custom Password Rules By Man ...

  2. Linux-压缩与归档

    压缩:gzip/gunzip.bzip2/bunzip2.xz/unxz 归档:tar ####归档+压缩:zip 1. gzip, gunzip, zcat - compress or expand ...

  3. netcore的Session使用小记

    之前说过,core需要什么功能就添加并使用什么中间件 照例,在Startup.cs的ConfigureServices方法中添加services.AddSession();再在Configure方法中 ...

  4. Google guava cache源码解析1--构建缓存器(1)

    此文已由作者赵计刚授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 1.guava cache 当下最常用最简单的本地缓存 线程安全的本地缓存 类似于ConcurrentHas ...

  5. “全栈2019”Java多线程第三十五章:如何获取线程被等待的时间?

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  6. 《Python黑帽子:黑客与渗透测试编程之道》 自动化攻击取证

    工具安装: 下载源码:https://code.google.com/archive/p/volatility/downloads 工具配置: 获取内存镜像:https://www.downloadc ...

  7. TmsTimeUtils 时间戳

    package com.sprucetec.tms.utils; import java.math.BigDecimal;import java.text.DateFormat;import java ...

  8. Mysql root账号general_log_file方法获取webshell

    在前面的phpmyadmin漏洞利用专题中介绍了如何通过root账号来获取webshell,但在现实情况中,由于Mysql版本较高以及配置文件的缘故,往往无法直接通过root账号写入网站真实路劲下获取 ...

  9. Swift5 语言指南(二十二) 扩展

    扩展为现有的类,结构,枚举或协议类型添加新功能.这包括扩展您无法访问原始源代码的类型的能力(称为追溯建模).扩展类似于Objective-C中的类别.(与Objective-C类别不同,Swift扩展 ...

  10. node.js中的回调

    同步和阻塞:这两个术语可以互换使用,指的是代码的执行会在函数返回之前停止.如果某个操作阻塞,那么脚本就无法继续,这意味着必须等待. 异步和非阻塞:这两个术语可以互换使用,指的是基于回调的.允许脚本并行 ...