Partager via


Entrée de texte avec la vue d’écriture manuscrite

Note

L’affichage de l’écriture manuscrite n’est pas pris en charge par les contrôles de texte dans WinUI dans le Kit de développement logiciel (SDK) d’application Windows. Cet article s’applique uniquement aux applications UWP.

La zone de texte se développe lorsqu’elle est tapée avec le stylet

Personnalisez la vue d’écriture manuscrite (pour l’entrée manuscrite en entrée de texte) intégrée aux contrôles d’entrée de texte UWP tels que TextBox, RichEditBox et AutoSuggestBox.

Aperçu

Les contrôles d’entrée de texte UWP prennent en charge l’entrée de stylet à l’aide de Windows Ink en se transformant en surface d’écriture manuscrite lorsqu’un utilisateur appuie dans une zone d’entrée de texte à l’aide d’un stylet.

Le texte est reconnu au fur et à mesure que l'utilisateur écrit n'importe où sur la surface d'écriture manuscrite, tandis qu'une fenêtre de suggestions présente les résultats de la reconnaissance. L’utilisateur peut appuyer sur un résultat pour le choisir ou continuer à écrire pour accepter le candidat proposé. Les résultats de reconnaissance littérale (lettre par lettre) sont inclus dans la fenêtre des candidats, donc la reconnaissance n’est pas limitée aux mots d’un dictionnaire. Lorsque l’utilisateur écrit, l’entrée de texte acceptée est convertie en police de script qui conserve l’impression d’écriture naturelle.

Note

La vue d’écriture manuscrite est activée par défaut, mais vous pouvez la désactiver par contrôle et revenir au panneau d’entrée de texte à la place.

Zone de texte avec encre et suggestions

Un utilisateur peut modifier son texte à l’aide de mouvements et d’actions standard :

  • frapper ou gratter - dessiner à travers pour supprimer un mot ou une partie d’un mot
  • joindre - dessiner un arc entre les mots pour supprimer l'espace entre eux.
  • insérer - dessiner un symbole de point d’insertion pour insérer un espace
  • remplacer : écrire sur du texte existant pour le remplacer

Zone de texte avec correction d'encre

Désactiver la vue d’écriture manuscrite

La vue d’écriture manuscrite intégrée est activée par défaut.

Vous pouvez désactiver la vue d’écriture manuscrite si vous fournissez déjà des fonctionnalités d’entrée manuscrite à texte équivalentes dans votre application, ou que votre expérience d’entrée de texte repose sur un type de mise en forme ou de caractère spécial (par exemple, un onglet) non disponible par le biais de l’écriture manuscrite.

Dans cet exemple, nous désactivons la vue d’écriture manuscrite en définissant la propriété IsHandwritingViewEnabled du contrôle TextBox sur false. Tous les contrôles de texte qui prennent en charge la vue d’écriture manuscrite prennent en charge une propriété similaire. ​

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

Spécifier l’alignement de la vue d’écriture manuscrite

La vue d’écriture manuscrite se trouve au-dessus du contrôle de texte sous-jacent et dimensionnée pour prendre en charge les préférences d’écriture manuscrite de l’utilisateur (voir Paramètres -> Appareils Bluetooth -> Stylet & Windows Ink -> Écriture manuscrite -> Taille de police). La vue est également alignée automatiquement par rapport au contrôle de texte et à son emplacement dans l’application.

L’interface utilisateur de l’application ne reflowe pas pour prendre en charge le contrôle plus grand, ce qui peut masquer l’interface utilisateur importante.

L’extrait de code suivant montre comment utiliser la propriété PlacementAlignment d’un TextBoxHandwritingView pour spécifier l’ancrage sur le contrôle de texte sous-jacent utilisé pour aligner la vue d’écriture manuscrite. ​

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

Désactiver les candidats à la saisie semi-automatique

La fenêtre contextuelle de suggestion de texte est activée par défaut. Il fournit la liste des principaux candidats à la reconnaissance manuscrite à partir desquels l’utilisateur peut sélectionner au cas où le candidat principal était incorrect.

Si votre application fournit déjà des fonctionnalités de reconnaissance personnalisée robustes, vous pouvez utiliser la propriété AreCandidatesEnabled pour désactiver les suggestions intégrées, comme illustré dans l’exemple suivant.

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

Utiliser les préférences de police d’écriture manuscrite

Un utilisateur peut choisir parmi une collection prédéfinie de polices basées sur l’écriture manuscrite à utiliser lors du rendu du texte basé sur la reconnaissance manuscrite (voir Paramètres -> Bluetooth & appareils -> Stylet & Windows Ink -> Écriture manuscrite -> Police).

Votre application peut accéder à ce paramètre et utiliser la police sélectionnée pour le texte reconnu dans le contrôle de texte.

Dans cet exemple, nous écoutons l’événement TextChanged d’une zone de texte et appliquons la police sélectionnée par l’utilisateur si la modification du texte provient de l’objet HandwritingView (ou d’une police par défaut, si ce n’est pas le cas). ​

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

Accéder à handwritingView dans les contrôles composites

Les contrôles composites qui utilisent le contrôle TextBox ou RichEditBox (par exemple , AutoSuggestBox), prennent également en charge un HandwritingView.

Pour accéder à handwritingView dans un contrôle composite, utilisez l’API VisualTreeHelper .

L’extrait de code XAML suivant affiche un contrôle AutoSuggestBox .

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

Dans le code-behind correspondant, nous montrons comment désactiver le HandwritingView sur autoSuggestBox.

  1. Tout d’abord, nous gérons l’événement Loaded de l’élément et appelons une FindInnerTextBox fonction pour démarrer la traversée de l’arborescence visuelle.

    private void SampleAutoSuggestBox_Loaded(object sender, RoutedEventArgs e)​
    {​
        if (FindInnerTextBox((AutoSuggestBox)sender))​
            autoSuggestInnerTextBox.IsHandwritingViewEnabled = false;​
    }​
    
  2. Dans la fonction FindInnerTextBox, nous itérons à travers l'arborescence visuelle (en commençant à partir d'un AutoSuggestBox) en appelant une fonction 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. Enfin, la FindVisualChildByName fonction effectue une itération dans l’arborescence visuelle jusqu’à ce que textBox soit récupéré.

    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);​
    }​
    ​```
    
    

Repositionner le HandwritingView

Dans certains cas, vous devrez peut-être vous assurer que le HandwritingView couvre des éléments de l’interface utilisateur qu’il ne couvrirait pas autrement.

Ici, nous créons un TextBox qui prend en charge la dictée (implémentée en plaçant un TextBox et un bouton de dictée dans un StackPanel).

Capture d’écran d’une zone de texte prenant en charge la dictée

Comme StackPanel est maintenant plus grand que le TextBox, le HandwritingView risque de ne pas masquer tout le contrôle composite.

Capture d’écran d’un contrôle HandwritingView qui obstrue partiellement une zone de texte, et une qui est repositionnée pour masquer complètement la zone de texte

Pour résoudre ce problème, définissez la propriété PlacementTarget du HandwritingView sur l’élément d’interface utilisateur auquel il doit être aligné.

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

Redimensionner le HandwritingView

Vous pouvez également définir la taille du HandwritingView, ce qui peut être utile lorsque vous devez vous assurer que la vue n’empêche pas l’interface utilisateur importante.

Comme dans l’exemple précédent, nous créons un TextBox qui prend en charge la dictée (implémentée en plaçant un TextBox et un bouton de dictée dans un StackPanel).

Capture d’écran d’un TextBox qui prend en charge la dictée

Dans ce cas, nous redimensionnons le HandwritingView pour vous assurer que le bouton de dictée est visible.

Capture d’écran d’un contrôle HandwritingView qui masque le bouton de dictée, et un contrôle redimensionné pour garantir que le bouton de dictée est visible

Pour ce faire, nous liez la propriété MaxWidth du HandwritingView à la largeur de l’élément d’interface utilisateur qu’il doit obstruer.

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

Repositionner l’interface utilisateur personnalisée

Si vous avez une interface utilisateur personnalisée qui apparaît en réponse à une entrée de texte, telle qu’une fenêtre contextuelle d’information, vous devrez peut-être repositionner cette interface utilisateur afin qu’elle n’empêche pas la vue d’écriture manuscrite.

TextBox avec une interface utilisateur personnalisée

L’exemple suivant montre comment écouter les événements Ouvert, Fermé et SizeChanged du HandwritingView pour définir la position d’une fenêtre contextuelle.

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);​    ​
}​

Reconfigurer le modèle du contrôle HandwritingView

Comme avec tous les contrôles d’infrastructure XAML, vous pouvez personnaliser la structure visuelle et le comportement visuel d’un HandwritingView pour vos besoins spécifiques.

Pour voir un exemple complet de création d’un modèle personnalisé, consultez la procédure créer des contrôles de transport personnalisés ou l’exemple De contrôle d’édition personnalisé. ​ ​ ​ ​ ​ ​ ​ ​