Udostępnij przez


Wprowadzanie tekstu w widoku pisma ręcznego

Uwaga / Notatka

Widok pisma ręcznego nie jest obsługiwany przez kontrolki tekstowe w WinUI w Windows App SDK. Ten artykuł dotyczy tylko aplikacji platformy UWP.

Pole tekstowe rozwija się po naciśnięciu piórem

Dostosuj widok pisma ręcznego (pismo odręczne do wprowadzania tekstu), który jest wbudowany w kontrolki wprowadzania tekstu platformy UWP, takie jak TextBox, RichEditBox i AutoSuggestBox.

Przegląd

Kontrolki wprowadzania tekstu platformy UWP obsługują wprowadzanie za pomocą pióra przy użyciu Windows Ink, przekształcając się w powierzchnię do pisma odręcznego, gdy użytkownik stuknie w pole wprowadzania tekstu przy użyciu pióra.

Tekst jest rozpoznawany, gdy użytkownik zapisuje w dowolnym miejscu na powierzchni do pisania odręcznego, podczas gdy w oknie sugestii są wyświetlane wyniki rozpoznawania. Użytkownik może nacisnąć wynik, aby go wybrać, lub kontynuować pisanie, aby zaakceptować proponowanego kandydata. Wyniki rozpoznawania poszczególnych liter są zawarte w oknie podglądu, więc rozpoznawanie nie jest ograniczone do wyrazów w słowniku. Podczas pisania przez użytkownika zaakceptowane dane wejściowe tekstu są konwertowane na czcionkę skryptu, która zachowuje charakter naturalnego pisania.

Uwaga / Notatka

Widok pisma ręcznego jest domyślnie włączony, ale można go wyłączyć dla poszczególnych kontrolek i zamiast tego przywrócić do panelu wprowadzania tekstu.

Pole tekstowe z atramentem i sugestiami

Użytkownik może edytować swój tekst przy użyciu standardowych gestów i akcji:

  • przekreślenie lub zmazanie — przeciągnij linię, aby usunąć słowo lub część słowa
  • join — narysuj łuk między wyrazami, aby usunąć przestrzeń między nimi
  • insert — rysowanie symbolu karetki w celu wstawienia spacji
  • overwrite — nadpisanie istniejącego tekstu, aby go zastąpić

Pole tekstowe z korektą pisma odręcznego

Wyłączanie widoku pisma ręcznego

Wbudowany widok pisma ręcznego jest domyślnie włączony.

Możesz wyłączyć widok pisma ręcznego, jeśli w aplikacji udostępniono już równoważną funkcjonalność pisma odręcznego do tekstu lub środowisko wprowadzania tekstu korzysta z pewnego rodzaju formatowania lub znaku specjalnego (na przykład karty) niedostępnego za pomocą pisma ręcznego.

W tym przykładzie wyłączymy widok pisma ręcznego, ustawiając właściwość IsHandwritingViewEnabled kontrolki TextBox na false. Wszystkie kontrolki tekstu obsługujące widok pisma ręcznego obsługują podobną właściwość. ​

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

Ustal wyrównanie widoku pisma ręcznego

Widok pisma ręcznego znajduje się nad podstawową kontrolką tekstową i jest odpowiednio dopasowany do preferencji użytkownika dotyczących pisma odręcznego (zobacz Ustawienia —> Bluetooth i urządzenia —> Pióro i Windows Ink —> Pismo odręczne —> Rozmiar czcionki). Widok jest również automatycznie wyrównany względem kontrolki tekstu oraz jej położenia w aplikacji.

Interfejs użytkownika aplikacji nie zmienia układu, aby dopasować się do większej kontroli, co może zasłonić ważne elementy interfejsu użytkownika.

Poniższy fragment kodu pokazuje, jak użyć właściwości PlacementAlignment kontrolki TextBoxHandwritingView , aby określić, która kotwica w podstawowej kontrolce tekstu jest używana do wyrównania widoku pisma ręcznego. ​

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

Wyłączanie kandydatów do automatycznego uzupełniania

Wyskakujące sugestie tekstowe są domyślnie włączone. Zawiera listę najbardziej trafnych kandydatów do rozpoznawania pisma ręcznego, z której użytkownik może dokonać wyboru, jeśli kandydat podstawowy jest niepoprawny.

Jeśli aplikacja zapewnia już niezawodne, niestandardowe funkcje rozpoznawania, możesz użyć właściwości AreCandidatesEnabled , aby wyłączyć wbudowane sugestie, jak pokazano w poniższym przykładzie.

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

Używanie preferencji czcionki pisma ręcznego

Użytkownik może wybrać spośród wstępnie zdefiniowanej kolekcji czcionek opartych na piśmie odręcznym do użycia podczas renderowania tekstu na podstawie rozpoznawania pisma odręcznego (zobacz Ustawienia —> Bluetooth i urządzenia —> Pióro i pismo ręczne —> Pismo ręczne —> Czcionka).

Aplikacja może uzyskać dostęp do tego ustawienia i użyć wybranej czcionki dla rozpoznanych tekstu w kontrolce tekstu.

W tym przykładzie nasłuchujemy zdarzenia TextChanged kontrolki TextBox i stosujemy wybraną czcionkę użytkownika, jeśli zmiana tekstu została dokonana z użyciem HandwritingView (lub stosujemy czcionkę domyślną, jeśli nie). ​

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

Uzyskiwanie dostępu do obiektu HandwritingView w kontrolkach złożonych

Kontrolki złożone korzystające z kontrolki TextBox lub RichEditBox (np. AutoSuggestBox) obsługują również kontrolkę HandwritingView.

Aby uzyskać dostęp do kontrolki HandwritingView w kontrolce złożonej, użyj interfejsu API VisualTreeHelper .

Poniższy fragment kodu XAML wyświetla kontrolkę AutoSuggestBox .

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

W odpowiednim kodzie pokazujemy, jak wyłączyć HandwritingView w AutoSuggestBox.

  1. Najpierw obsługujemy zdarzenie Załadowane elementu i wywołujemy FindInnerTextBox funkcję, aby rozpocząć przechodzenie drzewa wizualnego.

    private void SampleAutoSuggestBox_Loaded(object sender, RoutedEventArgs e)​
    {​
        if (FindInnerTextBox((AutoSuggestBox)sender))​
            autoSuggestInnerTextBox.IsHandwritingViewEnabled = false;​
    }​
    
  2. W ramach tej funkcji wykonujemy iterację po drzewie wizualnym (zaczynając od kontrolki AutoSuggestBox), wywołując funkcję FindInnerTextBox.

    private bool FindInnerTextBox(AutoSuggestBox autoSuggestBox)​
    {​
        if (autoSuggestInnerTextBox == null)​
        {​
            // Cache textbox to avoid multiple tree traversals. ​
            autoSuggestInnerTextBox = 
                (TextBox)FindVisualChildByName<TextBox>(autoSuggestBox);​
        }​
        return (autoSuggestInnerTextBox != null);​
    }​
    ​```
    
    
  3. Na koniec funkcja iteruje przez drzewo wizualne aż do momentu, gdy zostanie pobrany 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);​
    }​
    ​```
    
    

Zmienia położenie elementu HandwritingView

W niektórych przypadkach może być konieczne upewnienie się, że HandwritingView obejmuje elementy interfejsu użytkownika, których w przeciwnym razie może nie obejmować.

W tym miejscu tworzymy pole tekstowe obsługujące dyktowanie głosowe (implementowane przez umieszczenie TextBox i przycisku do dyktowania w StackPanel).

Zrzut ekranu przedstawiający pole tekstowe obsługujące dyktowanie

Ponieważ StackPanel jest teraz większy niż TextBox, HandwritingView może nie przesłonić całej kontrolki złożonej.

Zrzut ekranu przedstawiający kontrolkę HandwritingView, która częściowo zasłania kontrolkę TextBox oraz taką, która została przesunięta, aby całkowicie zasłaniać kontrolkę TextBox

Aby rozwiązać ten problem, ustaw właściwość PlacementTarget elementu HandwritingView na element interfejsu użytkownika, do którego ma być wyrównana.

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

Zmienianie rozmiaru obiektu HandwritingView

Można również ustawić rozmiar HandwritingView, co może być przydatne, gdy musisz upewnić się, że widok nie zasłania ważnego interfejsu użytkownika.

Podobnie jak w poprzednim przykładzie, tworzymy TextBox, który obsługuje dyktowanie (zaimplementowane przez umieszczenie TextBox i przycisku dyktowania w StackPanel).

Zrzut ekranu przedstawiający pole tekstowe obsługujące dyktowanie

W takim przypadku zmieniamy rozmiar kontrolki HandwritingView, aby upewnić się, że przycisk dyktowania jest widoczny.

Zrzut ekranu przedstawiający kontrolkę HandwritingView, która occluduje przycisk dyktowania, oraz kontrolkę o zmienionym rozmiarze, aby upewnić się, że przycisk dyktowania jest widoczny

W tym celu powiążemy właściwość MaxWidth obiektu HandwritingView z szerokością elementu interfejsu użytkownika, który powinien być zasłonięty.

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

Zmienia położenie niestandardowego interfejsu użytkownika

Jeśli masz niestandardowy interfejs użytkownika, który jest wyświetlany w odpowiedzi na wprowadzanie tekstu, takie jak informacyjne okienko, może być konieczne przemieszczenie tego interfejsu użytkownika, aby nie zasłaniał widoku pisma ręcznego.

Pole tekstowe z niestandardowym interfejsem użytkownika

W poniższym przykładzie pokazano, jak nasłuchiwać na zdarzenia Opened, Closed i SizeChanged elementu HandwritingView w celu ustawienia położenia 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);​    ​
}​

Przeszablonuj kontrolkę HandwritingView

Podobnie jak w przypadku wszystkich kontrolek struktury XAML, możesz dostosować zarówno strukturę wizualizacji, jak i zachowanie wizualne elementu HandwritingView pod kątem określonych wymagań.

Aby zapoznać się z pełnym przykładem tworzenia szablonu niestandardowego, zapoznaj się z instrukcjami Tworzenie niestandardowych kontrolek transportu lub przykładową kontrolką edycji niestandardowej. ​ ​ ​ ​ ​ ​ ​ ​