서식 있는 편집 상자

RichEditBox 컨트롤을 사용해 서식이 지정된 텍스트, 하이퍼링크 및 이미지가 포함된 서식 있는 텍스트 문서를 입력하고 편집할 수 있습니다. IsReadOnly 속성을 true로 설정하여 RichEditBox를 읽기 전용으로 만들 수 있습니다.

올바른 컨트롤인가요?

텍스트 파일을 표시하고 편집하려면 RichEditBox를 사용합니다. RichEditBox를 사용하여 다른 표준 텍스트 입력 상자를 사용하는 방식으로 앱에 사용자 입력을 가져오면 안 됩니다. 대신 앱과 별개의 텍스트 파일로 작업할 때 이를 사용합니다. 일반적으로 RichEditBox에 입력한 텍스트를 .rtf 파일로 저장합니다.

  • 여러 줄 입력란의 주된 목적이 읽기 전용 문서(예: 블로그 항목 또는 이메일 메시지의 본문)를 만드는 것이고 그 문서에 서식을 지정해야 하는 경우에는 서식 있는 텍스트 블록을 사용합니다.
  • 사용자에게만 사용되고 다시 표시되지 않는 텍스트를 캡처할 때는 일반 텍스트 입력 컨트롤을 사용합니다.
  • 기타 모든 시나리오에서는 일반 텍스트 입력 컨트롤을 사용합니다.

올바른 텍스트 컨트롤을 선택하는 방법에 대한 자세한 내용은 텍스트 컨트롤 문서를 참조하세요.

권장 사항

  • 서식 있는 텍스트 상자를 만들 때 스타일 단추를 제공하고 해당 작업을 구현합니다.
  • 앱의 스타일과 일치하는 글꼴을 사용합니다.
  • 텍스트 컨트롤의 높이는 기본 입력을 수용하기에 충분하게 만듭니다.
  • 사용자가 입력하는 동안 텍스트 입력 컨트롤의 높이가 늘어나도록 만들지 마세요.
  • 한 줄만 필요한 경우에는 여러 줄 입력란을 사용하지 마세요.
  • 일반 텍스트 컨트롤으로도 충분한 경우 서식 있는 텍스트 컨트롤을 사용하지 마세요.

예제

이 서식 있는 편집 상자에는 서식 있는 텍스트 문서가 열려 있습니다. 서식 지정 및 파일 단추는 서식 있는 편집 상자의 일부는 아니지만 최소한의 스타일 지정 단추 집합을 제공하고 해당 작업을 구현해야 합니다.

A rich text box with an open document

UWP 및 WinUI 2

Important

이 문서의 정보 및 예제는 Windows 앱 SDKWinUI 3를 사용하는 앱에 최적화되어 있지만 일반적으로 WinUI 2를 사용하는 UWP 앱에 적용할 수 있습니다. 플랫폼별 정보 및 예제는 UWP API 참조를 확인하세요.

이 섹션에는 UWP 또는 WinUI 2 앱에서 컨트롤을 사용하는 데 필요한 정보가 있습니다.

이 컨트롤용 API는 Windows.UI.Xaml.Controls 네임스페이스에 있습니다.

최신 WinUI 2를 사용하여 모든 컨트롤에 대한 최신 스타일과 템플릿을 가져오는 것이 좋습니다. WinUI 2.2 이상에는 둥근 모서리를 사용하는 이 컨트롤의 새 템플릿이 포함되어 있습니다. 자세한 내용은 모서리 반경을 참조하세요.

서식 있는 편집 상자 만들기

WinUI 3 갤러리 앱에는 대부분의 WinUI 3 컨트롤, 특징, 기능의 대화형 예제가 포함되어 있습니다. Microsoft Store에서 앱을 다운로드하거나 GitHub에서 소스 코드를 가져오세요.

기본적으로 RichEditBox는 맞춤법 검사를 지원합니다. 맞춤법 검사기를 사용하지 않도록 설정하려면 IsSpellCheckEnabled 속성을 false로 설정합니다. 자세한 내용은 맞춤법 검사 지침 문서를 참조하세요.

RichEditBox의 Document 속성을 사용하여 콘텐츠를 가져옵니다. Block 개체를 콘텐츠로 사용하는 RichTextBlock과 달리 RichEditBox의 콘텐츠는 ITextDocument 개체입니다. ITextDocument 인터페이스는 문서를 로드하고 스트림에 저장하고, 텍스트 범위를 검색하고, 활성 선택을 가져오고, 변경 실행을 취소하고 변경을 다시 실행하고, 기본 서식 지정 특성을 설정하는 등의 방법을 제공합니다.

이 예제는 RichEditBox에서 .rtf(서식 있는 텍스트 서식) 파일을 편집, 로드 및 저장하는 방법을 보여줍니다.

<RelativePanel Margin="20" HorizontalAlignment="Stretch">
    <RelativePanel.Resources>
        <Style TargetType="AppBarButton">
            <Setter Property="IsCompact" Value="True"/>
        </Style>
    </RelativePanel.Resources>
    <AppBarButton x:Name="openFileButton" Icon="OpenFile"
                  Click="OpenButton_Click" ToolTipService.ToolTip="Open file"/>
    <AppBarButton Icon="Save" Click="SaveButton_Click"
                  ToolTipService.ToolTip="Save file"
                  RelativePanel.RightOf="openFileButton" Margin="8,0,0,0"/>

    <AppBarButton Icon="Bold" Click="BoldButton_Click" ToolTipService.ToolTip="Bold"
                  RelativePanel.LeftOf="italicButton" Margin="0,0,8,0"/>
    <AppBarButton x:Name="italicButton" Icon="Italic" Click="ItalicButton_Click"
                  ToolTipService.ToolTip="Italic" RelativePanel.LeftOf="underlineButton" Margin="0,0,8,0"/>
    <AppBarButton x:Name="underlineButton" Icon="Underline" Click="UnderlineButton_Click"
                  ToolTipService.ToolTip="Underline" RelativePanel.AlignRightWithPanel="True"/>

    <RichEditBox x:Name="editor" Height="200" RelativePanel.Below="openFileButton"
                 RelativePanel.AlignLeftWithPanel="True" RelativePanel.AlignRightWithPanel="True"/>
</RelativePanel>
private async void OpenButton_Click(object sender, RoutedEventArgs e)
{
    // Open a text file.
    Windows.Storage.Pickers.FileOpenPicker open =
        new Windows.Storage.Pickers.FileOpenPicker();
    open.SuggestedStartLocation =
        Windows.Storage.Pickers.PickerLocationId.DocumentsLibrary;
    open.FileTypeFilter.Add(".rtf");

    Windows.Storage.StorageFile file = await open.PickSingleFileAsync();

    if (file != null)
    {
        try
        {
            Windows.Storage.Streams.IRandomAccessStream randAccStream =
        await file.OpenAsync(Windows.Storage.FileAccessMode.Read);

            // Load the file into the Document property of the RichEditBox.
            editor.Document.LoadFromStream(Windows.UI.Text.TextSetOptions.FormatRtf, randAccStream);
        }
        catch (Exception)
        {
            ContentDialog errorDialog = new ContentDialog()
            {
                Title = "File open error",
                Content = "Sorry, I couldn't open the file.",
                PrimaryButtonText = "Ok"
            };

            await errorDialog.ShowAsync();
        }
    }
}

private async void SaveButton_Click(object sender, RoutedEventArgs e)
{
    Windows.Storage.Pickers.FileSavePicker savePicker = new Windows.Storage.Pickers.FileSavePicker();
    savePicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.DocumentsLibrary;

    // Dropdown of file types the user can save the file as
    savePicker.FileTypeChoices.Add("Rich Text", new List<string>() { ".rtf" });

    // Default file name if the user does not type one in or select a file to replace
    savePicker.SuggestedFileName = "New Document";

    Windows.Storage.StorageFile file = await savePicker.PickSaveFileAsync();
    if (file != null)
    {
        // Prevent updates to the remote version of the file until we
        // finish making changes and call CompleteUpdatesAsync.
        Windows.Storage.CachedFileManager.DeferUpdates(file);
        // write to file
        Windows.Storage.Streams.IRandomAccessStream randAccStream =
            await file.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite);

        editor.Document.SaveToStream(Windows.UI.Text.TextGetOptions.FormatRtf, randAccStream);

        // Let Windows know that we're finished changing the file so the
        // other app can update the remote version of the file.
        Windows.Storage.Provider.FileUpdateStatus status = await Windows.Storage.CachedFileManager.CompleteUpdatesAsync(file);
        if (status != Windows.Storage.Provider.FileUpdateStatus.Complete)
        {
            Windows.UI.Popups.MessageDialog errorBox =
                new Windows.UI.Popups.MessageDialog("File " + file.Name + " couldn't be saved.");
            await errorBox.ShowAsync();
        }
    }
}

private void BoldButton_Click(object sender, RoutedEventArgs e)
{
    Windows.UI.Text.ITextSelection selectedText = editor.Document.Selection;
    if (selectedText != null)
    {
        Windows.UI.Text.ITextCharacterFormat charFormatting = selectedText.CharacterFormat;
        charFormatting.Bold = Windows.UI.Text.FormatEffect.Toggle;
        selectedText.CharacterFormat = charFormatting;
    }
}

private void ItalicButton_Click(object sender, RoutedEventArgs e)
{
    Windows.UI.Text.ITextSelection selectedText = editor.Document.Selection;
    if (selectedText != null)
    {
        Windows.UI.Text.ITextCharacterFormat charFormatting = selectedText.CharacterFormat;
        charFormatting.Italic = Windows.UI.Text.FormatEffect.Toggle;
        selectedText.CharacterFormat = charFormatting;
    }
}

private void UnderlineButton_Click(object sender, RoutedEventArgs e)
{
    Windows.UI.Text.ITextSelection selectedText = editor.Document.Selection;
    if (selectedText != null)
    {
        Windows.UI.Text.ITextCharacterFormat charFormatting = selectedText.CharacterFormat;
        if (charFormatting.Underline == Windows.UI.Text.UnderlineType.None)
        {
            charFormatting.Underline = Windows.UI.Text.UnderlineType.Single;
        }
        else {
            charFormatting.Underline = Windows.UI.Text.UnderlineType.None;
        }
        selectedText.CharacterFormat = charFormatting;
    }
}

텍스트 컨트롤에 맞는 키보드를 선택합니다.

사용자가 입력할 것으로 예상되는 데이터 종류와 일치하도록 텍스트 컨트롤의 입력 범위를 설정하여 터치 키보드나 SIP(Soft Input Panel)를 사용한 데이터 입력을 도울 수 있습니다. 기본 키보드 레이아웃은 일반적으로 서식 있는 텍스트 문서 작업에 적합합니다.

입력 범위를 사용하는 방법에 대한 자세한 내용은 입력 범위를 사용하여 터치 키보드 변경을 참조하세요.

샘플 코드 가져오기