Ввод текста в представлении рукописного ввода

Примечание.

Представление рукописного ввода не поддерживается текстовыми элементами управления в пакете SDK для приложений Windows. Эта статья относится только к приложениям UWP.

Text box expands when tapped with pen

Настройте представление рукописного ввода (для рукописного ввода в текст), встроенное в элементы управления вводом текста UWP, такие как TextBox, RichEditBox и AutoSuggestBox.

Обзор

Элементы управления вводом текста UWP поддерживают ввод пера с помощью Рукописного ввода Windows , преобразовав его в область рукописного ввода, когда пользователь нажимает на текстовое поле с помощью пера.

Текст распознается как пользователь записывает в любом месте области рукописного ввода, пока в окне кандидата отображаются результаты распознавания. Пользователь может коснуться результата, чтобы выбрать его, или продолжить писать, чтобы выбрать предлагаемое слово-кандидат. Буквальные (побуквенные) результаты распознавания добавляются в окно слов-кандидатов, поэтому распознавание не ограничивается словами из словаря. По мере того, как пользователь пишет, текст преобразуется в рукописный шрифт, создавая ощущение естественного письма.

Примечание.

Представление рукописного ввода включено по умолчанию, но его можно отключить отдельно для каждого элемента управления и вместо него вернуться к использованию панели ввода текста.

Text box with ink and suggestions

Пользователь может изменить текст с помощью стандартных жестов и действий:

  • зачеркнуть или вычеркнуть — провести линию поверх слова, чтобы удалить слово или его часть;
  • соединить — нарисовать дугу между словами, чтобы удалить пробел между ними;
  • вставить — нарисовать символ вставки, чтобы вставить пробел;
  • перезапись — запись поверх существующего текста для его замены.

Text box with ink correction

Отключение представления рукописного ввода

Встроенное представление рукописного ввода по умолчанию включено.

Представление рукописного ввода, если вы уже предоставляете эквивалентную функциональность рукописного ввода в своем приложении, или процесс ввода текста зависит от какого-либо рода форматирования или специальных символов (например, "Tab"), недоступных с помощью рукописного ввода, может потребоваться отключить.

В этом примере мы отключаем представление рукописного ввода, задав свойству IsHandwritingViewEnabled элемента управления TextBox значение false. Все элементы управления, которые поддерживают представление рукописного ввода, поддерживают аналогичное свойство. ​

<TextBox Name="SampleTextBox"​
    Height="50" Width="500" ​
    FontSize="36" FontFamily="Segoe UI" ​
    PlaceholderText="Try taping with your pen" ​
    IsHandwritingViewEnabled="False">​
</TextBox>​

Определение выравнивания для представления рукописного ввода

Представление рукописного ввода находится над базовым элементом управления текстом и размером, чтобы разместить настройки рукописного ввода пользователя (см. Параметры -> Bluetooth и устройства -> Перо и Windows Ink -> Рукописный ввод —> размер шрифта). Представление также автоматически выравнивается относительно текстового элемента управления и его расположения в приложении.

Пользовательский интерфейс приложения не переполняет для размещения более крупного элемента управления, что может привести к окклюде важного пользовательского интерфейса.

В следующем фрагменте кода показано, как использовать свойство PlacementAlignment объекта TextBoxHandwritingView, чтобы указать, какая привязка в базовом элементе управления текстом используется для выравнивания представления рукописного ввода. ​

<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>​

Отключение автоматического завершения слов-кандидатов

Всплывающее окно предложения текста включено по умолчанию. Он предоставляет список кандидатов на распознавание рукописных рукописей, из которых пользователь может выбрать в случае, если основной кандидат является неверным.

Если приложение уже предоставляет надежные пользовательские функции распознавания, можно использовать свойство AreCandidatesEnabledd для отключения встроенных предложений, как показано в следующем примере.

<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>

Использование настроек шрифта рукописного ввода

Пользователь может выбрать из предварительно определенной коллекции шрифтов на основе рукописного ввода, используемых при отрисовке текста на основе распознавания рукописного ввода (см. Параметры -> Bluetooth и устройства -> Перо и Windows Ink -> Рукописный ввод -> Шрифт).

Ваше приложение может получить доступ к этому параметру и использовать выбранный шрифт для распознанного текста в текстовом элементе управления.

В этом примере мы прослушиваем событие TextChanged текстового поля и применяем выбранный шрифт пользователя, если изменение текста произошло из рукописного представления (или шрифта по умолчанию, если нет). ​

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 в составном элементе управления, используйте API VisualTreeHelper.

В следующем фрагменте XAML отображается элемент управления AutoSuggestBox.

<AutoSuggestBox Name="SampleAutoSuggestBox"​ 
    Height="50" Width="500"​ 
    PlaceholderText="Auto Suggest Example"​ 
    FontSize="16" FontFamily="Segoe UI" ​ 
    Loaded="SampleAutoSuggestBox_Loaded">​
</AutoSuggestBox>​

В соответствующем фрагменте кода мы покажем, как отключить HandwritingView в AutoSuggestBox.

  1. Во-первых, мы обрабатываем событие загруженного элемента и вызываем 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 функция выполняет итерацию по визуальному дереву до получения Текстового поля .

    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 содержит элементы пользовательского интерфейса, которых в противном случае могло и не быть.

Здесь мы создаем элемент TextBox, который поддерживает диктовку (реализуется путем помещения TextBox и кнопки диктовки в StackPanel).

Screenshot of a Text Box that supports dictation

Так как StackPanel теперь больше текстового поля, рукописный ввод в Представление может не быть occlude всех составных элементов управления.

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

Чтобы решить эту проблему, установите для свойства PlacementTarget HandwritingView значение элемента пользовательского интерфейса, по которому он должен быть выровнен.

<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, что может быть полезно, когда вам нужно убедиться, что представление не перекрывает важный элемент пользовательского интерфейса.

Как и в предыдущем примере, мы создаем 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

Для этого мы привязываем свойство MaxWidth HandwritingView к ширине элемента пользовательского интерфейса, который он закрывает.

<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>​

Пользовательский интерфейс перепозиции

Если у вас есть пользовательский элемент интерфейса, который появляется в ответ на ввод текста, например, информационное всплывающее окно, вам может потребоваться изменить положение этого элемента интерфейса, чтобы он не перекрывал представление рукописного ввода.

TextBox with custom UI

В следующем примере показано, как прослушивать события Opened, Closed и SizeChangedHandwritingView, чтобы задать положение 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 для ваших конкретных требований.

Полный пример создания пользовательского шаблона проверка из примера "Создание пользовательских элементов управления транспортом" или "Настраиваемый элемент управления редактированием". ​ ​ ​ ​ ​ ​ ​ ​