从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. jQuery插件初级练习1答案

    html: <script> $(".btn").click(function(){ $.color($("#box"),"blue&qu ...

  2. Concurrency Programming Guide 并发设计指引(二)

    以下翻译是本人通过谷歌工具进行翻译,并进行修正后的结果,希望能对大家有所帮助.如果您发现翻译的不正确不合适的地方,希望您能够发表评论指正,谢谢.转载请注明出处. Concurrency and App ...

  3. 《A computer-aided healthcare system for cataract classification and grading based on fundus image analysis》学习笔记

    Abstract This paper presents a fundus image analysis based computer aided system for automatic class ...

  4. UNIGUI接收普通消息和被动回复用户消息

    接收普通消息和被动回复用户消息 用户发送消息给公众号时(或某些特定的用户操作引发的事件推送时),会产生一个POST请求,开发者可以在响应包(Get)中返回特定XML结构,来对该消息进行响应(现支持回复 ...

  5. UniGUI的TUniLoginForm窗口自定义背景色和背景图片

    雨田家园 UniGUI的TUniLoginForm窗口自定义背景色 uniGUI的TUniLoginForm类创建的登录窗口默认是不带颜色,可以自定义css风格来改变背景颜色. 一般是通过在UniSe ...

  6. Windows的cmd窗口显示utf8字符

    用XeLaTeX的时候,查字体需要用fc-list命令,XeLaTeX用的都是utf编码,所以fc-list输出的字体信息也是utf编码.因此需要把cmd窗口也改成utf8编码才能看到这些字体信息.U ...

  7. 托管博客到coding或者github

    1. 部署网站到github的pages服务 参考: <在Github上面搭建Hexo博客(一):部署到Github> <Hexo搭建独立博客,托管到Github和Coding上教程 ...

  8. devexpress gridview 添加按钮

    #region 添加按钮事件 private RepositoryItemButtonEdit CreateRepositoryItemButtonEdit(Dictionary<object, ...

  9. jQuery ajax 302跨域

    一.ajax 302 ajax用于异步获取服务器数据,但是某天有这么一个使用场景: > 基于安全考虑,登录的用户的信息失效时,系统的所有ajax接口都由服务器直接重定向到系统的登录页面,此时登录 ...

  10. Java中goto和break、continue实现区别

    goto 关键字很早就在程序设计语言中出现.事实上,goto 是汇编语言的程序控制结构的始祖:“若条件 A,则跳到这里:否则跳到那里”.若阅读由几乎所有编译器生成的汇编代码,就会发现程序控制里包含了许 ...