含手寫檢視的文字輸入

注意

Windows 應用程式 SDK 中的文字控制項不支援手寫檢視。 本文僅適用於 UWP 應用程式。

Text box expands when tapped with pen

自訂內建於 UWP 文字輸入控制項 (例如 TextBoxRichEditBoxAutoSuggestBox) 中的手寫檢視 (用於筆跡到文字輸入)。

概觀

當使用者使用手寫筆點選文字輸入方塊時,UWP 文字輸入控制項支援使用 Windows Ink 的手寫筆輸入。

文字可隨著使用者在手寫表面任何位置書寫時進行辨識,而候選字視窗會顯示辨識結果。 使用者可以點選結果來選擇,或繼續書寫以接受建議的候選字。 候選字視窗會包含逐字 (逐個字母) 辨識結果,因此辨識範圍並不局限於字典中的單字。 當使用者書寫時,接受的文字輸入會轉換為保有自然書寫風格的書寫體字型。

注意

預設會啟用手寫檢視,但是您可以按照每個控制項加以停用,並還原為文字輸入面板。

Text box with ink and suggestions

使用者可以使用標準手勢及動作來編輯他們的文字:

  • 刪除線或劃掉:一筆劃過,可刪除一個字或字的一部分
  • 聯結:在單字之間劃弧線,可刪除其間的空格
  • 插入:劃插入號可插入空格
  • 覆寫:在現有文字上面書寫,可加以取代

Text box with ink correction

停用手寫檢視

預設會啟用內建手寫檢視。

如果您已經在應用程式中提供同等的筆跡轉換文字功能,或您的文字輸入體驗依賴某種無法透過手寫提供的格式或特殊字元 (例如定位字元),則可能會想停用手寫檢視。

在此範例中,我們將 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。

以下程式碼片段展示如何使用 TextBoxHandwritingViewPlacementAlignment 屬性,指定基礎文字控制項上的哪個錨點會用來對齊手寫檢視。 ​

<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 - >手寫 - >字體)。

您的應用程式可以存取此設定,並將選取的字型使用於文字控制項中已辨識的文字。

在此範例中,我們會接聽 TextBoxTextChanged 事件,如果文字變更源自 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

使用 TextBoxRichEditBox 控制項 (例如 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

  1. 首先,我們會處理專案的 Loaded 事件,並呼叫函 FindInnerTextBox 式來啟動可視化樹狀結構周遊。

    private void SampleAutoSuggestBox_Loaded(object sender, RoutedEventArgs e)​
    {​
        if (FindInnerTextBox((AutoSuggestBox)sender))​
            autoSuggestInnerTextBox.IsHandwritingViewEnabled = false;​
    }​
    
  2. 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);​
    }​
    ​```
    
    
  3. 最後,此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 中)。

Screenshot of a Text Box that supports dictation

StackPanel 現在大於 TextBox,因此 HandwritingView 可能完全不會遮蔽複合控制項。

Screenshot of a HandwritingView control that partially occludes a TextBox, and one that is repositioned to fully occlude the TextBox

若要解決此問題,請將 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="&#xE720;" ​
        Background="White" Foreground="DarkGray" ​    Tapped="DictationButton_Tapped" />​
</StackPanel>​

調整 HandwritingView 的大小

您也可以設定 HandwritingView 的大小,當您必須確保檢視不會遮蔽重要 UI 時,這很有用。

如同先前的範例,我們會建立支援聽寫的 TextBox (實作方式為將 TextBox 和聽寫按鈕放入 StackPanel 中)。

Screenshot of a TextBox that supports dictation

在此情況下,我們會調整 HandwritingView 的大小,以確保顯示 [聽寫] 按鈕。

Screenshot of a HandwritingView control that occludes the dictation button, and one that is resized to ensure the dictation button is visible

若要這樣做,請將 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="&#xE720;" ​
        Background="White" Foreground="DarkGray" ​
        Tapped="DictationButton_Tapped" />​
</StackPanel>​

調整自訂 UI 的位置

如果您有可回應文字輸入的自訂 UI (例如資訊快顯視窗),您可能需要調整該 UI 的位置,使其不會遮蔽手寫檢視。

TextBox with custom UI

下列範例示範如何接聽 HandwritingViewOpenedClosedSizeChanged 事件,以設定 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 的視覺化結構和視覺化行為。

若要查看建立自訂範本的完整範例,請查看建立自訂傳輸控制項操作方法或自訂編輯控制項範例。 ​ ​ ​ ​ ​ ​ ​ ​