Partilhar via


Introdução de texto com o modo de escrita manual

Observação

A vista de escrita manual não é suportada por controlos de texto no WinUI no Windows App SDK. Este artigo aplica-se apenas a aplicações UWP.

A caixa de texto expande-se quando tocada com caneta

Personalize a vista de escrita manual (para entrada de tinta para texto) que está integrada nos controlos de entrada de texto UWP, como o TextBox, RichEditBox e AutoSuggestBox.

Visão geral

Os controlos de entrada de texto UWP suportam entrada por caneta usando Windows Ink , transformando-se numa superfície de escrita manual quando o utilizador toca numa caixa de texto usando uma caneta.

O texto é reconhecido quando o utilizador escreve em qualquer parte da superfície de escrita manual, enquanto uma janela candidata mostra os resultados do reconhecimento. O utilizador pode tocar num resultado para o escolher, ou continuar a escrever para aceitar o candidato proposto. Os resultados do reconhecimento literal (letra a letra) estão incluídos na janela de candidatos, de modo que o reconhecimento não se restringe a palavras em um dicionário. À medida que o utilizador escreve, a entrada de texto aceite é convertida para uma fonte script que mantém a sensação de escrita natural.

Observação

A vista de escrita manual está ativada por defeito, mas podes desativá-la por controlo e voltar ao painel de entrada de texto.

Caixa de texto com tinta e sugestões

Um utilizador pode editar o seu texto usando gestos e ações padrão:

  • Riscar ou riscar - Desenhar para eliminar uma palavra ou parte de uma palavra
  • join - desenhar um arco entre as palavras para eliminar o espaço entre elas
  • inserir - desenhar um símbolo de caret para inserir um espaço
  • Sobrescrever - Escrever sobre o texto existente para o substituir

Caixa de texto com correção de tinta

Desativar a vista de escrita manual

A vista de escrita incorporada está ativada por defeito.

Pode querer desativar a vista de escrita manual se já fornecer funcionalidade equivalente de tinta para texto na sua aplicação, ou se a sua experiência de introdução de texto depender de algum tipo de formatação ou carácter especial (como um tabulador) que não está disponível através da escrita manual.

Neste exemplo, desativamos a visualização de escrita manual definindo a propriedade IsHandwritingViewEnabled do controlo TextBox para false. Todos os controlos de texto que suportam a vista de escrita manual suportam uma propriedade semelhante. ​

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

Especifique o alinhamento da interface de escrita manual

A vista de escrita manual está localizada acima do controlo de texto subjacente e dimensionada para acomodar as preferências de escrita do utilizador (ver Definições -> Bluetooth & dispositivos -> Caneta & Windows Ink -> Caligrafia -> Tamanho da fonte). A visualização também é automaticamente alinhada em relação ao controlo de texto e à sua localização dentro da aplicação.

A interface do utilizador (UI) da aplicação não se ajusta para acomodar o controlo maior, o que pode ocultar elementos importantes da UI.

O excerto seguinte mostra como usar a propriedade PlacementAlignment de um TextBoxHandwritingView para especificar qual âncora no controlo de texto subjacente é usada para alinhar a vista de escrita manual. ​

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

Desativar candidatos de preenchimento automático

O pop-up de sugestões de texto está ativado por defeito. Fornece uma lista dos principais candidatos a reconhecimento de tinta, da qual o utilizador pode selecionar caso o candidato principal esteja incorreto.

Se a sua aplicação já oferece funcionalidade robusta e personalizada de reconhecimento, pode usar a propriedade AreCandidatesEnabled para desativar as sugestões incorporadas, como mostrado no exemplo seguinte.

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

Use preferências de fontes de caligrafia

O utilizador pode escolher entre uma coleção pré-definida de fontes baseadas em escrita manual para usar ao renderizar texto com base no reconhecimento de tinta (ver Definições -> Bluetooth & dispositivos -> Caneta e Tinta do Windows -> Caligrafia -> Fonte).

A sua aplicação pode aceder a esta definição e usar a fonte selecionada para o texto reconhecido no controlo de texto.

Neste exemplo, ouvimos o evento TextChanged de uma TextBox e aplicamos a fonte selecionada pelo utilizador se a alteração de texto tiver origem na HandwritingView (ou numa fonte padrão, se não). ​

private void SampleTextBox_TextChanged(object sender, TextChangedEventArgs e)​
{​
    ((TextBox)sender).FontFamily = 
        ((TextBox)sender).HandwritingView.IsOpen ?
            new FontFamily(PenAndInkSettings.GetDefault().FontFamilyName) : 
            new FontFamily("Segoe UI");​
}​

Acede à HandwritingView em controlos compostos

Controlos compostos que utilizam o controlo TextBox ou RichEditBox (como o AutoSuggestBox) também suportam uma HandwritingView.

Para aceder ao HandwritingView num controlo composto, use a API VisualTreeHelper.

O snippet XAML seguinte exibe um controlo AutoSuggestBox .

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

No código subjacente correspondente, demonstramos como desativar a HandwritingView na AutoSuggestBox.

  1. Primeiro, tratamos do evento Loaded do elemento e chamamos uma FindInnerTextBox função para iniciar a travessia visual da árvore.

    private void SampleAutoSuggestBox_Loaded(object sender, RoutedEventArgs e)​
    {​
        if (FindInnerTextBox((AutoSuggestBox)sender))​
            autoSuggestInnerTextBox.IsHandwritingViewEnabled = false;​
    }​
    
  2. Na função FindInnerTextBox, iteramos pela árvore visual (começando em AutoSuggestBox) chamando a função 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. Finalmente, a FindVisualChildByName função itera pela árvore visual até recuperar a 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);​
    }​
    ​```
    
    

Reposicionar a Janela de Escrita Manual

Em alguns casos, pode ser necessário garantir que o HandwritingView cobre elementos da interface que de outra forma não cobririam.

Aqui, criamos uma TextBox que suporta ditado (implementada colocando uma TextBox e um botão de ditado num StackPanel).

Captura de ecrã de uma caixa de texto que suporta ditado

Como o StackPanel é agora maior do que o TextBox, o HandwritingView pode não ocultar todo o controlo composto.

Captura de ecrã de um controlo HandwritingView que oclui parcialmente uma Caixa de Texto, e outro que é reposicionado para ocluir completamente a Caixa de Texto

Para resolver isto, defina a propriedade PlacementTarget do HandwritingView para o elemento UI ao qual deve estar alinhada.

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

Redimensionar a Vista da Escrita Manuscrita

Também podes definir o tamanho da HandwritingView, o que pode ser útil quando precisas de garantir que a vista não oclude interfaces importantes.

Tal como no exemplo anterior, criamos uma TextBox que suporta ditado (implementada colocando uma TextBox e um botão de ditado num StackPanel).

Captura de ecrã de uma TextBox que suporta ditado

Neste caso, redimensionamos a HandwritingView para garantir que o botão de ditado é visível.

Captura de ecrã de um controlo HandwritingView que oculta o botão de ditado, e outro que é redimensionado para garantir que o botão de ditado é visível

Para isso, associamos a propriedade MaxWidth do HandwritingView à largura do elemento UI que deve ocultar.

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

Reposicionar interface personalizada

Se tiveres uma interface personalizada que aparece em resposta à entrada de texto, como um pop-up informativo, talvez precises de reposicionar essa interface para que não obstrua a vista de escrita manual.

TextBox com interface personalizada

O exemplo seguinte mostra como ouvir os eventos Opened, Closed e SizeChanged do HandwritingView para definir a posição de um 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);​    ​
}​

Redesenhar o controlo HandwritingView

Como em todos os controlos do framework XAML, pode personalizar tanto a estrutura visual como o comportamento visual de um HandwritingView para os seus requisitos específicos.

Para ver um exemplo completo de criação de um modelo personalizado, consulte o tutorial Criar controlos de transporte personalizados ou o exemplo de Controlo de Edição Personalizado. ​ ​ ​ ​ ​ ​ ​ ​