Casella di modifica RTF

È possibile usare un controllo RichEditBox per immettere e modificare documenti RTF contenenti testo formattato, collegamenti ipertestuali e immagini. È possibile rendere di sola lettura un controllo RichEditBox impostando la relativa proprietà IsReadOnly su true.

È il controllo giusto?

Usare un controllo RichEditBox per visualizzare e modificare file di testo. Il controllo RichEditBox non si usa per ottenere l'input dell'utente nell'app come si usano altre caselle di input di testo standard. Piuttosto è possibile usarlo per lavorare con file di testo separati dall'app. In genere il testo immesso in un RichEditBox viene salvato in un file .rtf.

  • Se lo scopo principale della casella di testo su più righe è la creazione di documenti di sola lettura (ad esempio voci di blog o contenuti di un messaggio email) e tali documenti necessitano di testo formattato, usa in alternativa una casella di testo RTF.
  • Quando si acquisisce testo che verrà solo usato e non rivisualizzato agli utenti, usare un controllo di input di testo normale.
  • Per tutti gli altri scenari, usare un controllo di input di testo normale.

Per altre informazioni su come scegliere il controllo di testo più appropriato, vedi l'articolo Controlli di testo.

Consigli

  • Quando crei una casella di testo in formato RTF, fornisci pulsanti per l'impostazione dello stile e implementane le azioni.
  • Usa un tipo di carattere coerente con lo stile dell'app.
  • Imposta per il controllo di testo un'altezza sufficiente per le immissioni tipiche.
  • Non lasciare che l'altezza dei controlli di input di testo aumenti mentre gli utenti digitano.
  • Non usare una casella di testo su più righe quando per gli utenti è necessaria una sola riga.
  • Non usare un controllo di testo RTF se è sufficiente un controllo di testo normale.

Esempi

In questa casella di modifica RTF è aperto un documento RTF. I pulsanti di formattazione e file non fanno parte della casella di modifica RTF, ma è necessario fornire almeno un set minimo di pulsanti di stile e implementare le relative azioni.

A rich text box with an open document

Piattaforma UWP e WinUI 2

Importante

Le informazioni e gli esempi in questo articolo sono ottimizzati per le app che usano Windows App SDK e WinUI 3, ma sono generalmente applicabili alle app UWP che usano WinUI 2. Per informazioni ed esempi specifici della piattaforma, consultare le indicazioni di riferimento sulle API UWP.

Questa sezione contiene informazioni necessarie per usare il controllo in un'app UWP o WinUI 2.

Le API per questo controllo sono presenti nello spazio dei nomi Windows.UI.Xaml.Controls.

È consigliabile usare la versione più recente di WinUI 2 per ottenere gli stili e i modelli più recenti per tutti i controlli. WinUI 2.2 o versioni successive include un nuovo modello per questo controllo che usa angoli arrotondati. Per altre informazioni, vedere Raggio dell'angolo.

Creare una casella di modifica RTF

L'app Raccolta WinUI 3 include esempi interattivi della maggior parte dei controlli e delle funzionalità di WinUI 3. Scaricare l'app da Microsoft Store od ottenere il codice sorgente su GitHub

Per impostazione predefinita, la classe RichEditBox supporta il controllo ortografico. Per disabilitare il controllo ortografico, impostare la proprietà IsSpellCheckEnabled su false. Per altre informazioni, vedere l'articolo Linee guida per il controllo ortografico.

Usare la proprietà Document della classe RichEditBox per ottenere il relativo contenuto. Il contenuto di una classe RichEditBox è un oggetto ITextDocument, diverso dal controllo RichTextBlock che usa gli oggetti Block come contenuto. L'interfaccia ITextDocument consente di caricare e salvare il documento in un flusso, recuperare intervalli di testo, ottenere la selezione attiva, annullare e ripetere le modifiche, impostare gli attributi di formattazione predefiniti e così via.

Questo esempio mostra come modificare, caricare e salvare un file Rich Text Format (RTF) in un controllo RichEditBox.

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

Scegliere la tastiera giusta per il controllo di testo

Per aiutare gli utenti a immettere dati con la tastiera virtuale, o SIP (Soft Input Panel), puoi impostare l'ambito di input del controllo di testo in modo che corrisponda al tipo di dati che l'utente deve immettere. Il layout di tastiera predefinito è in genere appropriato per l'uso di documenti RTF.

Per altre info su come usare gli ambiti di input, vedi Usare l'ambito di input per modificare la tastiera virtuale.

Scaricare il codice di esempio