大家好,由於很多原因,我有很長一段時間沒有在 CSDN 上分享我的學習成果了,如今終於可以回歸分享之路了。
之前在做一個項目的時候,想在一個區域里繪制自己的圖形,於是上網搜索資料,無意中找到了 InkCanvas ,但我們最終並沒有在項目里使用它,不過它的強大確深深地印在了我的腦海中。之后學院年級會舉辦一個比賽,本來沒打算參加,不過一覺醒來被告知室友已經給我報上名了,無奈之下只得借助 WPF 中的 InkCanvas 來趕出一個作品。
不過這次經歷讓我熟悉了 InkCanvas 的一些基本使用,之前在網上搜到的資料都不是很滿意,於是這里給大家奉上我的學習成果。
首先來簡單介紹一下什么是 InkCanvas 。顧名思義, InkCanvas 和 Canvas 有一定的聯系,都是一種畫布,我們可以在上面繪制我們的圖形等等。
那么 InkCanvas 和 Canvas 有什么區別呢?那就是 InkCanvas 集成了一些很方便的功能,使我們不必再用代碼去實現那些功能,下面將結合實例講解如何使用這些功能。
現在先來創建一個 WPF 應用程序,然后創建一個 InkCanvas 標簽。
- <Window x:Class="Blog_InkCanvas.MainWindow"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- Title="MainWindow" Height="350" Width="525">
- <Grid>
- <InkCanvas x:Name="inkCanvas"/>
- </Grid>
- </Window>
運行程序並且按住鼠標左鍵即可自右繪制墨跡。
InkCanvas 提供的最基本的功能是自由筆,我們這里稱顯示出來的圖形為墨跡,而繪制出來的墨跡實際上是 Stroke 類型,所以我們可以用 Stroke 類型的 DrawingAttributes 屬性進行墨跡的一些設置,例如顏色,粗細等等。
那么既然如此,我們就先來改變一下墨跡的顏色,將前面的 XAML 文件對應的后置代碼文件的內容修改為如下所示:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Data;
- using System.Windows.Documents;
- using System.Windows.Input;
- using System.Windows.Media;
- using System.Windows.Media.Imaging;
- using System.Windows.Navigation;
- using System.Windows.Shapes;
- using System.Windows.Ink;
- namespace Blog_InkCanvas
- {
- /// <summary>
- /// MainWindow.xaml 的交互邏輯
- /// </summary>
- public partial class MainWindow : Window
- {
- //聲明一個 DrawingAttributes 類型的變量
- DrawingAttributes drawingAttributes;
- public MainWindow()
- {
- InitializeComponent();
- //創建 DrawingAttributes 類的一個實例
- drawingAttributes = new DrawingAttributes();
- //將 InkCanvas 的 DefaultDrawingAttributes 屬性的值賦成創建的 DrawingAttributes 類的對象的引用
- //InkCanvas 通過 DefaultDrawingAttributes 屬性來獲取墨跡的各種設置,該屬性的類型為 DrawingAttributes 型
- inkCanvas.DefaultDrawingAttributes = drawingAttributes;
- //設置 DrawingAttributes 的 Color 屬性設置顏色
- drawingAttributes.Color = Colors.Red;
- }
- }
- }
再次運行程序,會發現墨跡顏色變成了紅色。
接下來我們同樣是通過 DrawingAttributes 對象來改變墨跡的各項設置,在上面的代碼后面添加如下代碼:
- //利用 DrawingAttributes 的 Width 和 Height 屬性來設置墨跡的寬度和高度
- //注意墨跡的寬度和高度是兩個概念
- //寬度在垂直方向上能顯現出來,而高度在水平方向上能顯現出來
- drawingAttributes.Width = 20;
- drawingAttributes.Height = 10;
- //利用 DrawingAttributes 的StylusTip 屬性可以設置墨跡觸筆的形狀,默認值是 StylusTip.Ellipse
- //將墨跡的寬度和高度都設置為稍大一些可以清楚的看到差別,如果較小則不太容易看出差別
- //這里寬度和高度都已經較大了,所以很容易看出差別,讀者可以把下面一行代碼反復注釋或取消注釋觀察幾次
- drawingAttributes.StylusTip = StylusTip.Rectangle;
繼續運行程序。
InkCanvas 還提供了平滑處理功能。
- //將 FitToCurve 屬性設置為 true 會在你繪制完一次墨跡后自動利用貝塞爾曲線來對你的墨跡進行平滑處理
- //為了使效果更明顯,測試時請盡可能地使所繪制的墨跡顯得雜亂無章,這樣繪制完成后即可看到效果
- //這個就不截圖演示了
- drawingAttributes.FitToCurve = true;
InkCanvas 還有兩個屬性,一個是 IsHeighlighter ,另一個是 IgnorePressure ,這兩個屬性都是布爾值,前者是判斷墨跡是否有熒光筆效果,后者是判斷墨跡的粗細是否隨壓力的增大而增大。
- //設置 IsHighlighter 屬性為 true ,則墨跡顯示的時候看上去像是熒光筆
- //官方文檔上說這樣做會使 Stroke 變的透明一些,可以顯示覆蓋住的墨跡,但是我感覺不太像透明,大家可以自己試試,也歡迎糾正
- drawingAttributes.IsHighlighter = false;
- //按照微軟官方文檔上的說法,設置 IgnorePressure 屬性為 true墨跡粗細會隨壓力的增大而增大
- //但同時也說了 XAML 一般不使用此屬性,我也實在找不到如何利用鼠標來進行壓力的變化
- //所以這里我想大家做個了解應該就可以了
- drawingAttributes.IgnorePressure = true;
前面介紹了 InkCanvas 墨跡的一些屬性,但是 InkCanvas 的強大遠遠不止這些,它還有幾個非常好用的功能。請看如下代碼:
- <Window x:Class="Blog_InkCanvas.MainWindow"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- Title="MainWindow" Height="350" Width="525">
- <Grid>
- <Grid.RowDefinitions>
- <RowDefinition Height="9*"/>
- <RowDefinition/>
- </Grid.RowDefinitions>
- <InkCanvas x:Name="inkCanvas" Grid.Row="0"/>
- <Grid Grid.Row="1">
- <Grid.ColumnDefinitions>
- <ColumnDefinition/>
- <ColumnDefinition/>
- <ColumnDefinition/>
- <ColumnDefinition/>
- <ColumnDefinition/>
- </Grid.ColumnDefinitions>
- <RadioButton Click="RadioButton_Click" Grid.Column="0">繪制墨跡</RadioButton>
- <RadioButton Click="RadioButton_Click" Grid.Column="1">按點擦除</RadioButton>
- <RadioButton Click="RadioButton_Click" Grid.Column="2">按線擦除</RadioButton>
- <RadioButton Click="RadioButton_Click" Grid.Column="3">選中墨跡</RadioButton>
- <RadioButton Click="RadioButton_Click" Grid.Column="4">停止操作</RadioButton>
- </Grid>
- </Grid>
- </Window>
將主頁面 XAML 代碼修改如上面,並在原來的后置 .cs 文件的構造函數之后添加如下方法:
- //更改 InkCanvas 對象的 EditingMode 屬性,可以改變要在 InkCanvas 上執行的操作
- //該屬性的值是一個 InkCanvasEditingMode 枚舉,常見功能如下
- private void RadioButton_Click(object sender, RoutedEventArgs e)
- {
- if((sender as RadioButton).Content.ToString() == "繪制墨跡")
- {
- //繪制墨跡
- inkCanvas.EditingMode = InkCanvasEditingMode.Ink;
- }
- else if((sender as RadioButton).Content.ToString() == "按點擦除")
- {
- //使用橡皮擦按點擦除墨跡
- inkCanvas.EditingMode = InkCanvasEditingMode.EraseByPoint;
- }
- else if ((sender as RadioButton).Content.ToString() == "按線擦除")
- {
- //使用橡皮擦按繪制的墨跡將某一筆墨跡擦除掉,注意是某一筆,如果多次繪制但是有交叉也是不可以的
- inkCanvas.EditingMode = InkCanvasEditingMode.EraseByStroke;
- }
- else if ((sender as RadioButton).Content.ToString() == "選中墨跡")
- {
- //選中某一筆墨跡,進行拖動和縮放以及按 Delete 鍵刪除,注意是某一筆
- inkCanvas.EditingMode = InkCanvasEditingMode.Select;
- }
- else if ((sender as RadioButton).Content.ToString() == "停止操作")
- {
- //不做任何
- inkCanvas.EditingMode = InkCanvasEditingMode.None;
- }
- }
InkCanvas 的EditingMode 屬性還有其他幾個值,但是基本的就是這幾個了,詳細信息請參看 MSDN 。運行程序,並選擇相應功能,即可看到效果。
利用 InkCanvas 不僅可以完成 Canvas 的功能,還可以非常方便地使用其他一些操作,對於繪圖類功能開發來說非常好用。
另外有一點需要注意,在 InkCanvas 上繪制的 Stroke 墨跡並不是 InkCanvas 對象 Children 集合類型屬性里的元素,所有用該屬性的 Clear() 方法是不能清除已繪制上去的墨跡的。
本文就到此結束了,希望大家多多批評指正,謝謝!