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 ...
随机推荐
- js反选
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...
- 如何判断ScrollView滑动方向
1/判断滚动视图左右滚动 { CGFloat startContentOffsetX;//滚动开始的坐标 CGFloat willEndContentOffsetX; //滚动即将停止的坐标 CGFl ...
- TryEnterCriticalSection___Delphi
VOID EnterCriticalSection:非阻塞函数.将当前线程对指定临界区的引用计数减1:在使用计数变为零时,另一等待此临界区的一个线程将被唤醒. BOOL TryEnterCritica ...
- 分形之树(Tree)
似乎每一个有关分形的教程都要讲到分形树,大概是因为树是生活中最常见的分形实物吧.这一节将展示下如何一步一步地生长出一棵树来.其实现算法不难,就是在每一次生长迭代中,使线段生长出几条新的线段来. 核心代 ...
- python做数据分析pandas库介绍之DataFrame基本操作
怎样删除list中空字符? 最简单的方法:new_list = [ x for x in li if x != '' ] 这一部分主要学习pandas中基于前面两种数据结构的基本操作. 设有DataF ...
- react-native项目之样式总结
react native(以下简称rn)里面涉及到的样式规则都是在js文件中写的,一改pc端的在样式文件中定义规则,所以pc端开发习惯的童鞋转向开发rn项目时,可能会对样式感到有些奇怪:其实react ...
- Codeforces 1058 D. Vasya and Triangle(分解因子)
题目:http://codeforces.com/contest/1058/problem/D 题意:有一个大小为N*M的矩阵内,构造一个三角形,使面积为(n*m)/k.若存在输出三个顶点(整数). ...
- Linux 中指定启动 tomcat 的 jdk 版本
环境: RHEL6.5. tomcat8.5.jdk1.8.0_181 修改 catalina.sh.setclasspath.sh 文件 进入目录 $ cd /data01/server/apach ...
- js中的stopImmediatePropagation方法和stopPropagation方法的区别
看到e.stopImmediatePropagation()这个方法时,记忆有点模糊了.特地回顾一下. 基本概念 stopImmediatePropagation方法:该方法作用在当前节点及事件链的所 ...
- 使用json-server模拟REST API
https://segmentfault.com/a/1190000005793257 在开发过程中,前后端不论是否分离,接口多半是滞后于页面开发的.所以建立一个REST风格的API接口,给前端页面提 ...