去年犯小人,萬事不順,4月剛換工作,開始新工作
遇到一個小問題,需要讀取圖片,然后對圖片進行定點縮放,很簡答的邏輯,很簡單的代碼,但是,這尼瑪我被wpf給坑了,這一坑就是三天
好了,很簡單的一個UI
<Canvas x:Name="canvas"> <Image Stretch="Fill" Name="image" Source="test.png"></Image> </Canvas>
為什么用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)); /// <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 為什么用依賴屬性而不用屬性
一方面它是一個自動綁定兩方面通知,另一方面,還有一個一個回調機制,方便處理,界面看起來更平滑,易於維護和觀賞性
源代碼:
下載源代碼(你妹,終於知道怎么設置連接了)