去年犯小人,万事不顺,4月刚换工作,开始新工作
遇到一个小问题,需要读取图片,然后对图片进行定点缩放,很简答的逻辑,很简单的代码,但是,这尼玛我被wpf给坑了,这一坑就是三天
好了,很简单的一个UI
为什么用Canvas,而不用Grid,这两个布局是一样的呢?
原因很简单,我们要用到Canvas.Set()这类函数进行移位下面我们就图解一下定点缩放的所谓思路吧,小二,上图这尼玛图片有点坑爹是吧.....
一个正方形,鼠标位置在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)); ////// Image的y坐标 /// 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 为什么用依赖属性而不用属性
一方面它是一个自动绑定两方面通知,另一方面,还有一个一个回调机制,方便处理,界面看起来更平滑,易于维护和观赏性
源代码:
(你妹,终于知道怎么设置连接了)