필기 보기를 사용한 텍스트 입력Text input with the handwriting view

펜으로 탭하면 텍스트 상자가 확장됨

TextBox, RichEditBoxAutoSuggestBox 같은 컨트롤에서 파생된 컨트롤처럼 Windows 텍스트 컨트롤이 지원하는 잉크를 텍스트로 입력을 위한 기본 제공 필기 보기를 사용자 지정합니다.Customize the built-in handwriting view for ink to text input supported by Windows text controls such as the TextBox, RichEditBox, and controls derived from these such as the AutoSuggestBox.

개요Overview

XAML 텍스트 입력 상자는 Windows Ink를 사용한 펜 입력을 지원합니다.XAML text input boxes feature embedded support for pen input using Windows Ink. 사용자가 Windows 펜을 사용하여 텍스트 입력 상자를 탭하면 별도의 입력 패널이 열리는 대신 텍스트 상자가 필기 화면으로 변환됩니다.When a user taps into a text input box using a Windows pen, the text box transforms into a handwriting surface, rather than opening a separate input panel.

사용자가 텍스트 상자의 아무 곳에 필기하면 텍스트가 인식되고, 후보 창에 인식 결과가 표시됩니다.Text is recognized as the user writes anywhere in the text box, and a candidate window shows the recognition results. 사용자는 결과를 터치하여 선택하거나 필기를 계속하여 제안된 후보를 수락할 수 있습니다.The user can tap a result to choose it, or continue writing to accept the proposed candidate. 리터럴(글자별) 인식 결과가 후보 창에 포함되므로 인식 범위가 사전의 단어로 제한되지 않습니다.The literal (letter-by-letter) recognition results are included in the candidate window, so recognition is not restricted to words in a dictionary. 사용자가 필기하면 수락된 텍스트 입력이 스크립트 글꼴로 변환되므로 자연스럽게 필기하는 느낌이 유지됩니다.As the user writes, the accepted text input is converted to a script font that retains the feel of natural writing.

참고

필기 보기는 기본적으로 사용하도록 설정되지만, 컨트롤마다 사용하지 않도록 설정하고 텍스트 입력 패널로 되돌릴 수 있습니다.The handwriting view is enabled by default, but you can disable it on a per-control basis and revert to the text input panel instead.

잉크와 추천 항목을 제공하는 텍스트 상자

사용자는 표준 제스처 및 다음 작업을 사용하여 텍스트를 편집할 수 있습니다.A user can edit their text using standard gestures and actions, like these:

  • 취소선 또는 지우기 - 단어나 단어의 일부를 삭제하는 관통선 그리기strike through or scratch out - draw through to delete a word or part of a word
  • 조인 - 단어 사이에 호를 그려서 단어 간 공백 삭제join - draw an arc between words to delete the space between them
  • 삽입 - 캐럿 기호를 그려서 공백 삽입insert - draw a caret symbol to insert a space
  • 덮어쓰기 - 기존 텍스트 위에 써서 기존 텍스트를 대체overwrite - write over existing text to replace it

잉크로 수정된 텍스트 상자

필기 보기 사용 안 함Disable the handwriting view

기본 필기 보기는 기본적으로 사용됩니다.The built-in handwriting view is enabled by default.

애플리케이션에서 이미 동일한 잉크-텍스트 변환 기능을 제공하고 있거나 텍스트 입력 환경이 필기를 통해 사용할 수 없는 형식 지정 또는 특수 문자를 사용하는 경우에는 필기 보기를 사용하지 않도록 설정할 수 있습니다.You might want to disable the handwriting view if you already provide equivalent ink-to-text functionality in your application, or your text input experience relies on some kind of formatting or special character (such as a tab) not available through handwriting.

이 예에서는 TextBox 컨트롤의 IsHandwritingViewEnabled 속성을 false로 설정하여 필기 보기를 사용하지 않겠습니다.In this example, we disable the handwriting view by setting the IsHandwritingViewEnabled property of the TextBox control to false. 필기 보기를 지원하는 모든 텍스트 컨트롤은 비슷한 속성을 지원합니다.All text controls that support the handwriting view support a similar property.

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

필기 보기의 맞춤 지정Specify the alignment of the handwriting view

필기 보기는 기본 텍스트 컨트롤 위에 있으며 사용자의 필기 기본 설정에 맞게 크기가 조정됩니다(설정 -> 디바이스 -> 펜 및 Windows Ink -> 필기 -> 텍스트 필드에 직접 쓸 때 글꼴 크기 참조).The handwriting view is located above the underlying text control and sized to accommodate the user's handwriting preferences (see Settings -> Devices -> Pen & Windows Ink -> Handwriting -> Size of font when writing directly into text field). 이 보기는 자동으로 앱 내의 텍스트 컨트롤 및 위치를 기준으로 맞춰집니다.The view is also automatically aligned relative to the text control and its location within the app.

애플리케이션 UI는 더 큰 컨트롤에 맞게 재배치되지 않으므로 시스템 보기가 중요한 UI를 가릴 수 있습니다.The application UI does not reflow to accommodate the larger control, so the system might cause the view to occlude important UI.

여기서는 TextBox HandwritingViewPlacementAlignment 속성을 사용하여 기본 텍스트 컨트롤의 어떤 앵커를 필기 보기 맞춤에 사용할 것인지 지정합니다.Here, we show how to use the PlacementAlignment property of a TextBox HandwritingView to specify which anchor on the underlying text control is used to align the handwriting view.

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

자동 완성 후보 사용 안 함Disable auto-completion candidates

최상위 후보가 올바르지 않은 경우 사용자가 상위 잉크 인식 후보 목록에서 선택할 수 있도록 텍스트 제안 팝업이 기본적으로 사용됩니다.The text suggestion popup is enabled by default to provide a list of top ink recognition candidates from which the user can select in case the top candidate is incorrect.

애플리케이션에서 이미 강력한 사용자 지정 인식 기능을 제공하는 경우 다음 예제처럼 AreCandidatesEnabled 속성을 사용하여 기본 제안을 사용하지 않도록 설정할 수 있습니다.If your application already provides robust, custom recognition functionality, you can use the AreCandidatesEnabled property to disable the built-in suggestions, as shown in the following example.

<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 handwriting font preferences

사용자는 잉크 인식에 따라 미리 정의된 필기 기반 글꼴 컬렉션에서 텍스트를 렌더링할 때 사용할 글꼴을 선택할 수 있습니다(설정-> 디바이스 -> 펜 및 Windows Ink -> 필기를 사용할 때 글꼴 -> 참조).A user can choose from a pre-defined collection of handwriting-based fonts to use when rendering text based on ink recognition (see Settings -> Devices -> Pen & Windows Ink -> Handwriting -> Font when using handwriting).

참고

사용자는 자신의 필기를 기반으로 글꼴을 만들 수도 있습니다.Users can even create a font based on their own handwriting.

앱은 이 설정에 액세스하여 텍스트 컨트롤에서 인식된 텍스트에 대해 선택된 글꼴을 사용할 수 있습니다.Your app can access this setting and use the selected font for the recognized text in the text control.

이 예제에서는 TextBoxTextChanged 이벤트를 수신 대기하다가 텍스트 변경이 HandwritingView에서 시작한 경우 사용자가 선택한 글꼴을 적용합니다(그렇지 않으면 기본 글꼴 적용).In this example, we listen for the TextChanged event of a TextBox and apply the user's selected font if the text change originated from the HandwritingView (or a default font, if not).

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 액세스Access the HandwritingView in composite controls

AutoSuggestBox처럼 TextBox 또는 RichEditBox 컨트롤을 사용하는 복합 컨트롤 역시 HandwritingView를 지원합니다.Composite controls that use the TextBox or RichEditBox controls, such as AutoSuggestBox also support a HandwritingView.

복합 컨트롤의 HandwritingView에 액세스하려면 VisualTreeHelper API를 사용합니다.To access the HandwritingView in a composite control, use the VisualTreeHelper API.

다음 XAML 코드 조각은 AutoSuggestBox 컨트롤을 표시합니다.The following XAML snippet displays an AutoSuggestBox control.

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

해당 코드 숨김에서는 AutoSuggestBox에서 HandwritingView를 해제하는 방법을 보여줍니다.In the corresponding code-behind, we show how to disable the HandwritingView on the AutoSuggestBox.

  1. 먼저, 애플리케이션의 Loaded 이벤트를 처리합니다. 여기서 시각적 트리 순회를 시작하는 FindInnerTextBox 함수를 호출합니다.First, we handle the application's Loaded event where we call a FindInnerTextBox function to start the visual tree traversal.

    private void SampleAutoSuggestBox_Loaded(object sender, RoutedEventArgs e)
    {
        if (FindInnerTextBox((AutoSuggestBox)sender))
            autoSuggestInnerTextBox.IsHandwritingViewEnabled = false;
    }
    
  2. 그런 다음, FindInnerTextBox 함수에서 FindVisualChildByName을 호출하여 시각적 트리를 반복합니다(AutoSuggestBox부터).We then begin iterating through the visual tree (starting at an AutoSuggestBox) in the FindInnerTextBox function with a call to 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. 마지막으로, 이 함수는 TextBox가 검색될 때까지 시각적 트리를 반복합니다.Finally, this function iterates through the visual tree until the TextBox is retrieved.

    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 위치 변경Reposition the HandwritingView

HandwritingView의 범위에 UI 요소가 포함되는지 확인하고, 그렇지 않으면 포함해야 하는 경우가 있습니다.In some cases, you might need to ensure that the HandwritingView covers UI elements that it otherwise might not.

여기서는 받아쓰기를 지원하는 TextBox를 만듭니다(StackPanel에 TextBox와 받아쓰기 단추를 배치하여 구현).Here, we create a TextBox that supports dictation (implemented by placing a TextBox and a dictation button into a StackPanel).

받아쓰기를 지원하는 텍스트 상자의 스크린샷

이제 StackPanel이 TextBox보다 크기 때문에 HandwritingView가 모든 복합 컨트롤을 가리지는 않을 것입니다.As the StackPanel is now larger than the TextBox, the HandwritingView might not occlude all of the composite cotnrol.

TextBox를 부분적으로 가리는 HandwritingView 컨트롤과 TextBox를 완전히 가리도록 위치가 변경된 컨트롤의 스크린샷

이 문제를 해결하려면 HandwritingView의 PlacementTarget 속성을 맞춰야 하는 UI 요소로 설정합니다.To address this, set the PlacementTarget property of the HandwritingView to the UI element to which it should be aligned.

<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 크기 조정Resize the HandwritingView

HandwritingView의 크기를 설정할 수도 있습니다. 보기가 중요한 UI를 가리지 않아야 할 때 유용한 기능입니다.You can also set the size of the HandwritingView, which can be useful when you need to ensure the view doesn't occlude important UI.

이전 예제와 마찬가지로, 받아쓰기를 지원하는 TextBox를 만듭니다(StackPanel에 TextBox와 받아쓰기 단추를 배치하여 구현).Like the previous example, we create a TextBox that supports dictation (implemented by placing a TextBox and a dictation button into a StackPanel).

받아쓰기를 지원하는 TextBox의 스크린샷

이 경우 받아쓰기 단추가 표시되도록 HandwritingView의 크기를 조정합니다.In this case, we resize the HandwritingView to ensure that the dictation button is visible.

받아쓰기 단추를 가리고 받아쓰기 단추가 보이도록 크기가 조정된 HandwritingView 컨트롤의 스크린샷

그러기 위해 HandwritingView의 MaxWidth 속성을 가려야 하는 UI 요소의 너비로 바인딩합니다.To do this, we bind the MaxWidth property of the HandwritingView to the width of the UI element that it should occlude.

<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 위치 변경Reposition custom UI

정보 팝업처럼 텍스트 입력에 응답하여 나타나는 사용자 지정 UI가 있는 경우 필기 보기를 가리지 않도록 UI 위치를 변경해야 할 수도 있습니다.If you have custom UI that appears in response to text input, such as an informational popup, you might need to reposition that UI so it doesn't occlude the handwriting view.

사용자 지정 UI가 있는 TextBox

다음 예제에서는 Popup의 위치를 설정하기 위해 HandwritingViewOpened, ClosedSizeChanged 이벤트를 수신 대기하는 방법을 보여줍니다.The following example shows how to listen for the Opened, Closed, and SizeChanged events of the HandwritingView to set the position of a 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 컨트롤의 템플릿 다시 작성Retemplate the HandwritingView control

모든 XAML 프레임워크 컨트롤과 마찬가지로, 요구 사항에 맞게 HandwritingView의 시각적 구조와 시각적 동작을 사용자 지정할 수 있습니다.As with all XAML framework controls, you can customize both the visual structure and visual behavior of a HandwritingView for your specific requirements.

사용자 지정 템플릿을 만드는 전체 예제는 사용자 지정 전송 컨트롤 만들기 방법 또는 사용자 지정 편집 컨트롤 샘플을 확인하세요.To see a full example of creating a custom template check out the Create custom transport controls how-to or the Custom Edit Control sample.