含手寫檢視的文字輸入
注意
Windows 應用程式 SDK 中的文字控制項不支援手寫檢視。 本文僅適用於 UWP 應用程式。
自訂內建於 UWP 文字輸入控制項 (例如 TextBox、RichEditBox 和 AutoSuggestBox) 中的手寫檢視 (用於筆跡到文字輸入)。
概觀
當使用者使用手寫筆點選文字輸入方塊時,UWP 文字輸入控制項支援使用 Windows Ink 的手寫筆輸入。
文字可隨著使用者在手寫表面任何位置書寫時進行辨識,而候選字視窗會顯示辨識結果。 使用者可以點選結果來選擇,或繼續書寫以接受建議的候選字。 候選字視窗會包含逐字 (逐個字母) 辨識結果,因此辨識範圍並不局限於字典中的單字。 當使用者書寫時,接受的文字輸入會轉換為保有自然書寫風格的書寫體字型。
注意
預設會啟用手寫檢視,但是您可以按照每個控制項加以停用,並還原為文字輸入面板。
使用者可以使用標準手勢及動作來編輯他們的文字:
- 刪除線或劃掉:一筆劃過,可刪除一個字或字的一部分
- 聯結:在單字之間劃弧線,可刪除其間的空格
- 插入:劃插入號可插入空格
- 覆寫:在現有文字上面書寫,可加以取代
停用手寫檢視
預設會啟用內建手寫檢視。
如果您已經在應用程式中提供同等的筆跡轉換文字功能,或您的文字輸入體驗依賴某種無法透過手寫提供的格式或特殊字元 (例如定位字元),則可能會想停用手寫檢視。
在此範例中,我們將 TextBox 控制項的 IsHandwritingViewEnabled 屬性設為 false,藉此停用手寫檢視。 支援手寫檢視的所有文字控制項都支援類似的屬性。
<TextBox Name="SampleTextBox"
Height="50" Width="500"
FontSize="36" FontFamily="Segoe UI"
PlaceholderText="Try taping with your pen"
IsHandwritingViewEnabled="False">
</TextBox>
指定手寫檢視的對齊方式
手寫視圖位於底層文字控制項上方,其大小適合使用者的手寫首選項 (請參閱設定 - >藍牙&裝置 - >Pen&Windows Ink - >手寫 - >字體大小)。 相對於文字控制項及其在應用程式內的位置,此檢視也會自動對齊。
應用程式 UI 不會重排以適應更大的控制項,因為可能會遮蔽重要的 UI。
下列代碼段示範如何使用 TextBox HandwritingView 的 PlacementAlignment 屬性來指定基礎文字控件上用來對齊手寫檢視的錨點。
<TextBox Name="SampleTextBox"
Height="50" Width="500"
FontSize="36" FontFamily="Segoe UI"
PlaceholderText="Try taping with your pen">
<TextBox.HandwritingView>
<HandwritingView PlacementAlignment="TopLeft"/>
</TextBox.HandwritingView>
</TextBox>
停用自動完成候選項目
預設會啟用文字建議彈出視窗。 它提供了頂級筆跡識別候選列表,使用者可以從中進行選擇,以防主要候選不正確。
如果您的應用程式已經提供了強大的自訂識別功能,您可以使用 AreCandidatesEnabled 屬性來停用內建建議,如以下範例所示。
<TextBox Name="SampleTextBox"
Height="50" Width="500"
FontSize="36" FontFamily="Segoe UI"
PlaceholderText="Try taping with your pen">
<TextBox.HandwritingView>
<HandwritingView AreCandidatesEnabled="False"/>
</TextBox.HandwritingView>
</TextBox>
使用手寫字型喜好設定
使用者可以從預先定義的基於手寫的字體集合中進行選擇,以便在基於筆跡識別渲染文字時使用 (請參閱設定 - >藍牙&裝置 - >Pen&Windows Ink - >手寫 - >字體)。
您的應用程式可以存取此設定,並將選取的字型使用於文字控制項中已辨識的文字。
在此範例中,我們會接聽 TextBox 的 TextChanged 事件,如果文字變更源自 HandwritingView 則套用使用者選取的字型 (如果不是,則套用預設字型)。
private void SampleTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
((TextBox)sender).FontFamily =
((TextBox)sender).HandwritingView.IsOpen ?
new FontFamily(PenAndInkSettings.GetDefault().FontFamilyName) :
new FontFamily("Segoe UI");
}
存取複合控制項中的 HandwritingView
使用 TextBox 或 RichEditBox 控制項 (例如 AutoSuggestBox) 的複合控制項也支援 HandwritingView。
若要存取複合控制項中的 HandwritingView,請使用 VisualTreeHelper API。
下列 XAML 程式碼片段會顯示 AutoSuggestBox 控制項。
<AutoSuggestBox Name="SampleAutoSuggestBox"
Height="50" Width="500"
PlaceholderText="Auto Suggest Example"
FontSize="16" FontFamily="Segoe UI"
Loaded="SampleAutoSuggestBox_Loaded">
</AutoSuggestBox>
在對應的程式碼後置中,我們會示範如何停用 AutoSuggestBox上的 HandwritingView。
首先,我們會處理專案的 Loaded 事件,並呼叫函
FindInnerTextBox
式來啟動可視化樹狀結構周遊。private void SampleAutoSuggestBox_Loaded(object sender, RoutedEventArgs e) { if (FindInnerTextBox((AutoSuggestBox)sender)) autoSuggestInnerTextBox.IsHandwritingViewEnabled = false; }
在
FindInnerTextBox
函式中,我們透過呼叫函式來迭代視覺化樹 (從 AutoSuggestBox 開始)FindVisualChildByName
。private bool FindInnerTextBox(AutoSuggestBox autoSuggestBox) { if (autoSuggestInnerTextBox == null) { // Cache textbox to avoid multiple tree traversals. autoSuggestInnerTextBox = (TextBox)FindVisualChildByName<TextBox>(autoSuggestBox); } return (autoSuggestInnerTextBox != null); } ```
最後,此
FindVisualChildByName
函式會逐一查看視覺化樹狀結構,直到擷取 TextBox 為止。private FrameworkElement FindVisualChildByName<T>(DependencyObject obj) { FrameworkElement element = null; int childrenCount = VisualTreeHelper.GetChildrenCount(obj); for (int i = 0; (i < childrenCount) && (element == null); i++) { FrameworkElement child = (FrameworkElement)VisualTreeHelper.GetChild(obj, i); if ((child.GetType()).Equals(typeof(T)) || (child.GetType().GetTypeInfo().IsSubclassOf(typeof(T)))) { element = child; } else { element = FindVisualChildByName<T>(child); } } return (element); } ```
調整 HandwritingView 的位置
在某些情況下,您可能需要確保 HandwritingView 涵蓋它可能沒有的 UI 元素。
在此,我們會建立支援聽寫的 TextBox (實作方式為將 TextBox 和聽寫按鈕放入 StackPanel 中)。
StackPanel 現在大於 TextBox,因此 HandwritingView 可能完全不會遮蔽複合控制項。
若要解決此問題,請將 HandwritingView 的 PlacementTarget 屬性設定為它應該對齊的 UI 元素。
<StackPanel Name="DictationBox"
Orientation="Horizontal"
VerticalAlignment="Top"
HorizontalAlignment="Left"
BorderThickness="1" BorderBrush="DarkGray"
Height="55" Width="500" Margin="50">
<TextBox Name="DictationTextBox"
Width="450" BorderThickness="0"
FontSize="24" VerticalAlignment="Center">
<TextBox.HandwritingView>
<HandwritingView PlacementTarget="{Binding ElementName=DictationBox}"/>
</TextBox.HandwritingView>
</TextBox>
<Button Name="DictationButton"
Height="48" Width="48"
FontSize="24"
FontFamily="Segoe MDL2 Assets"
Content=""
Background="White" Foreground="DarkGray" Tapped="DictationButton_Tapped" />
</StackPanel>
調整 HandwritingView 的大小
您也可以設定 HandwritingView 的大小,當您必須確保檢視不會遮蔽重要 UI 時,這很有用。
如同先前的範例,我們會建立支援聽寫的 TextBox (實作方式為將 TextBox 和聽寫按鈕放入 StackPanel 中)。
在此情況下,我們會調整 HandwritingView 的大小,以確保顯示 [聽寫] 按鈕。
若要這樣做,請將 HandwritingView 的 MaxWidth 屬性繫結至它應該遮蔽的 UI 元素寬度。
<StackPanel Name="DictationBox"
Orientation="Horizontal"
VerticalAlignment="Top"
HorizontalAlignment="Left"
BorderThickness="1"
BorderBrush="DarkGray"
Height="55" Width="500"
Margin="50">
<TextBox Name="DictationTextBox"
Width="450"
BorderThickness="0"
FontSize="24"
VerticalAlignment="Center">
<TextBox.HandwritingView>
<HandwritingView
PlacementTarget="{Binding ElementName=DictationBox}"
MaxWidth="{Binding ElementName=DictationTextBox, Path=Width"/>
</TextBox.HandwritingView>
</TextBox>
<Button Name="DictationButton"
Height="48" Width="48"
FontSize="24"
FontFamily="Segoe MDL2 Assets"
Content=""
Background="White" Foreground="DarkGray"
Tapped="DictationButton_Tapped" />
</StackPanel>
調整自訂 UI 的位置
如果您有可回應文字輸入的自訂 UI (例如資訊快顯視窗),您可能需要調整該 UI 的位置,使其不會遮蔽手寫檢視。
下列範例示範如何接聽 HandwritingView的 Opened、Closed和 SizeChanged 事件,以設定 Popup 的位置。
private void Search_HandwritingViewOpened(
HandwritingView sender, HandwritingPanelOpenedEventArgs args)
{
UpdatePopupPositionForHandwritingView();
}
private void Search_HandwritingViewClosed(
HandwritingView sender, HandwritingPanelClosedEventArgs args)
{
UpdatePopupPositionForHandwritingView();
}
private void Search_HandwritingViewSizeChanged(
object sender, SizeChangedEventArgs e)
{
UpdatePopupPositionForHandwritingView();
}
private void UpdatePopupPositionForHandwritingView()
{
if (CustomSuggestionUI.IsOpen)
CustomSuggestionUI.VerticalOffset = GetPopupVerticalOffset();
}
private double GetPopupVerticalOffset()
{
if (SearchTextBox.HandwritingView.IsOpen)
return (SearchTextBox.Margin.Top + SearchTextBox.HandwritingView.ActualHeight);
else
return (SearchTextBox.Margin.Top + SearchTextBox.ActualHeight);
}
重新建立 HandwritingView 控制項的範本
透過所有的 XAML 架構控制項,您可以針對您特定的需求來自訂 HandwritingView 的視覺化結構和視覺化行為。