更新:
WPF版有更新:參考WPF:使用InkPresenter來繪畫(更新)
以前寫過一篇Windows Phone 7: 使用FrameReported做一個簡單的繪圖程式,是通過用觸控FrameReporter事件來在InkPresenter中繪圖,而這篇文章用的是最基礎的滑鼠事件來完成的,同時支援擦除功能。在Windows Phone環境下,開發人員只能InkPresenter。不過對於WPF環境來說,使用更強大的InkPresenter的封裝控制項InkCanvas也是可以的,不過本文樣本全部是以InkPresenter的。
運行效果:
程式運行邏輯就緊密圍繞著XAML中的InkPresenter控制項的執行,具體環境可能會有一些細小的差異,不過總體上是很相似的。繪畫通過UIElement定義的基本滑鼠事件,然後在事件中向InkPresenter的Strokes屬性中添加Stroke對象,而Stroke對象則包括具體的點,也就是StylusPoint對象。在Windows Phone下,直接使用MouseEventArgs.StylusDevice.GetStylusPoints可以直接返回一個StylusPoint,使用起來更方便些。而在WPF下,MouseEventArgs.StylusDevice通常是null,因此只能使用MouseEventArgs.GetPosition方法。
其次WPF中Stroke對象的建立必須傳入一個StylusPointCollection對象,同時這個集合必須包含有一個點,也就是StylusPoint對象。而在Windows Phone中沒有這個限制。
擦除功能是通過StrokeCollection類型的HitTest方法來完成,在WPF下,HitTest更傾向於對Point的支援,如下WPF下StrokeCollection.HitTest方法重載:
public StrokeCollection HitTest(Point point);
public StrokeCollection HitTest(IEnumerable<Point> lassoPoints, int percentageWithinLasso);
public StrokeCollection HitTest(IEnumerable<Point> path, StylusShape stylusShape);
public StrokeCollection HitTest(Point point, double diameter);
public StrokeCollection HitTest(Rect bounds, int percentageWithinBounds);
而在Windows Phone下,只能通過StylusPointCollection對象:
public StrokeCollection HitTest(StylusPointCollection stylusPointCollection);
因此在執行擦除功能時,WPF可以可以在MouseMove事件中,直接傳入當前點作進行HitTest,而Windows Phone下,則需要保持紀錄一個StylusPointCollection集合。
最後WPF的InkPresenter貌似不去響應任何滑鼠事件,因此需要在其外面放一個控制項(比如Border)作為滑鼠事件存取點。
控制項使用起來很簡單,通過一個InkPresenter來建立內部的InkDrawing類型(WPF和Windows Phone的的執行會稍微有些不同),然後就可以繪圖了。它的DrawingAttributes屬性設定畫筆的樣式。IsMouseCaptureEnabled和IsMouseDrawingEnable屬性可以設定是否捕獲滑鼠事件和是否允許滑鼠繪圖,預設都是True。最後Mode屬性可以設定繪圖和擦除兩種模式。
目前的版本的程式和原始碼下載
下載頁面
注意:連結是微軟SkyDrive頁面,下載時請用瀏覽器直接下載,用某些下載工具可能無法下載
原始碼環境:
WPF:Microsoft Visual Studio Express 2012 for Windows Desktop
Windows Phone:Microsoft Visual Studio Express 2012 for Windows Phone