去年犯小人,万事不顺,4月刚换工作,开始新工作

遇到一个小问题,需要读取图片,然后对图片进行定点缩放,很简答的逻辑,很简单的代码,但是,这尼玛我被wpf给坑了,这一坑就是三天

好了,很简单的一个UI

    <Canvas x:Name="canvas">
<Image Stretch="Fill" Name="image" Source="test.png"></Image>
</Canvas>

为什么用Canvas,而不用Grid,这两个布局是一样的呢?
原因很简单,我们要用到Canvas.Set()这类函数进行移位
下面我们就图解一下定点缩放的所谓思路吧,小二,上图
wpf图片定点缩放-LMLPHP

这尼玛图片有点坑爹是吧.....

一个正方形,鼠标位置在15,5,以这个点进行缩放那缩放后的位置应该是12.5,7.5,图片有个属性是Scale,是缩放比例,1是正常,0.5是一半,依次类推
那就这好办了,根据当前坐标和图片坐标进行一个相减,然后除以比例系数Scale,进行移位就行了

  public double ImagePointX
{
get { return (double)GetValue(ImagePointXProperty); }
set { SetValue(ImagePointXProperty, value); }
}
public static readonly DependencyProperty ImagePointXProperty =
DependencyProperty.Register("ImagePointX", typeof(double), typeof(MainWindow), new PropertyMetadata(0d, ImagePointXChangedCallBack)); /// <summary>
/// Image的y坐标
/// </summary>
public double ImagePointY
{
get { return (double)GetValue(ImagePointYProperty); }
set
{
SetValue(ImagePointYProperty, value);
}
}
public static readonly DependencyProperty ImagePointYProperty =
DependencyProperty.Register("ImagePointY", typeof(double), typeof(MainWindow), new PropertyMetadata(0d, ImagePointYChangedCallBack));

我们设置两个依赖属性,定义image的x,y,在

    private void Window_MouseWheel(object sender, MouseWheelEventArgs e)

内写方法,进行相应的变换,在代码里都有,代码在最下面
很简单,点击鼠标移动,点击滑轮定点缩放\

作为一个有良知的愤青,我自己都会问自己,

这么简单的一个东西还值得你这熊孩子上传所谓的代码??

鄙人这里有两个问题

1 为什么用属性,而不用Canvas.GetLeft()或者Canvas.GetTop来获取图片的位置

这就是坑爹的地方!

  double currentScal = Scale / 0.5;
Scale += 0.5; var currentPoint = Mouse.GetPosition(this);
image.Width = ImageWidth * Scale;
image.Height = ImageHeight * Scale; ImagePointX = ImagePointX - (currentPoint.X - ImagePointX) / currentScal;
ImagePointY = ImagePointY - (currentPoint.Y - ImagePointY) / currentScal;

看这里,看这里,看上面的代码,这里是简单的比例压缩,

ImagePointX是当前image的x坐标,如果用Canvas.GetLeft会怎么样?
        var currentPoint = Mouse.GetPosition(this);
image.Width = ImageWidth * Scale;
image.Height = ImageHeight * Scale; //ImagePointX = ImagePointX - (currentPoint.X - ImagePointX) / currentScal;
//ImagePointY = ImagePointY - (currentPoint.Y - ImagePointY) / currentScal; var left = Canvas.GetLeft(image);
var top = Canvas.GetTop(image);
left = left - (currentPoint.X - left) / currentScal;
top = top - (currentPoint.Y - top) / currentScal;
Canvas.SetLeft(image, left);
Canvas.SetTop(image, top);

效果是一样的
Canvas是实时获取元素位置,在界面上,元素可能有自己模板,里面包含了多个元素,这时候获取的位置就不一定准确(由于是自己项目代码和界面不方便拿出来),这里只是做个介绍,我碰到的就是界面中获取元素位置的时候元素没有刷新,而只能用属性保存元素的上一个位置,当时我跟踪坐标,计算,计算了三天,获取的永远是没有更新的坐标,当鼠标移动后,Canvas才开始更新正确,宁死不知道什么原因,后来用属性的方式,解决了,回头继续研究它为什么没有刷新,原因就在于界面之间的路由和鼠标事件的顺序,与其每次去读取,不如用属性来设置,毕竟,我喜欢数字和程序,因为数字和程序不会骗人

2 为什么用依赖属性而不用属性

一方面它是一个自动绑定两方面通知,另一方面,还有一个一个回调机制,方便处理,界面看起来更平滑,易于维护和观赏性

源代码:

下载源代码(你妹,终于知道怎么设置连接了)

05-20 22:55