Quickstart: adding text input and editing controls (XAML)

[ This article is for Windows 8.x and Windows Phone 8.x developers writing Windows Runtime apps. If you’re developing for Windows 10, see the latest documentation ]

The XAML framework includes several controls for entering and editing text, and a set of properties for formatting the text. The text-entry controls are TextBox,PasswordBox, and RichEditBox. This quickstart shows you how you can use these text controls to display, enter, and edit text.

Roadmap: How does this topic relate to others? See:

Prerequisites

We assume that you can create a basic Windows Runtime app using C++, C#, or Visual Basic. For instructions on adding a control, see Quickstart: Adding controls and handling events.

Choosing a text control

The XAML framework includes 3 core text-entry controls: TextBox, PasswordBox, and RichEditBox. The text control that you use depends on your scenario. Here are some scenarios and the recommended control.

Scenario Recommended Control

Enter or edit plain text, such as in a form.

TextBox

Enter a password.

PasswordBox

Edit a document, article, or blog that requires formatting, paragraphs, hyperlinks, or inline images.

RichEditBox

 

TextBox

You can use a TextBox control to enter and edit unformatted text. You can use the Text property to get and set the text in a TextBox. Here's the XAML for a simple TextBox with it's Text property set.

<TextBox  Height="35" Width="200" Text="Hello World!" Margin="20"/>

Here's the TextBox that results from this XAML.

You can make a TextBox read-only by setting the IsReadOnly property to true. To make the text in a multi-line TextBox wrap, set the TextWrapping property to Wrap and the AcceptsReturn property to true.

You can get or set the selected text in a TextBox using the SelectedText property. Use the SelectionChanged event to do something when the user selects or de-selects text.

Here, we have an example of these properties and methods in use. When you select text in the first TextBox, the selected text is displayed in the second TextBox, which is read-only. The values of the SelectionLength and SelectionStart properties are shown in two TextBlocks. This is done using the SelectionChanged event.

<TextBox x:Name="textBox1" Height="75" Width="300" Margin="10"
         Text="The text that is selected in this TextBox will show up in the read only TextBox below." 
         TextWrapping="Wrap" AcceptsReturn="True"
         SelectionChanged="TextBox1_SelectionChanged" />
<TextBox x:Name="textBox2" Height="75" Width="300" Margin="5" 
         TextWrapping="Wrap" AcceptsReturn="True" IsReadOnly="True"/>
<TextBlock x:Name="label1" HorizontalAlignment="Center"/>
<TextBlock x:Name="label2" HorizontalAlignment="Center"/>
// C#
private void TextBox1_SelectionChanged(object sender, RoutedEventArgs e)
{
    textBox2.Text = textBox1.SelectedText;
    label1.Text = "Selection length is " + textBox1.SelectionLength.ToString();
    label2.Text = "Selection starts at " + textBox1.SelectionStart.ToString();
}
' VB
Private Sub TextBox1_SelectionChanged(sender As Object, e As RoutedEventArgs)
    textBox2.Text = textBox1.SelectedText
    label1.Text = "Selection length is " + textBox1.SelectionLength.ToString()
    label2.Text = "Selection starts at " + textBox1.SelectionStart.ToString()
End Sub

Here's the result of this code.

PasswordBox

You can enter a single line of non-wrapping content in a PasswordBox control. The user cannot view the entered text; only password characters that represents the text are displayed. You can specify this password character by using the PasswordChar property, and you can specify the maximum number of characters that the user can enter by setting the MaxLength property.

You get the text that the user entered from the Password property, typically in the handler for the PasswordChanged event.

Here's the XAML for a password box control that demonstrates the default look of the PasswordBox. When the user enters a password, it is checked to see if it is the literal value, "Password". If it is, we display a message to the user.

<PasswordBox x:Name="pwBox" Height="35" Width="200"
             MaxLength="8" PasswordChanged="pwBox_PasswordChanged"/>
           
<TextBlock x:Name="statusText" Margin="10" HorizontalAlignment="Center" />
// C#
private void pwBox_PasswordChanged(object sender, RoutedEventArgs e)
{
    if (pwBox.Password == "Password")
    {
        statusText.Text = "'Password' is not allowed as a password.";
    }
}
' VB
Private Sub pwBox_PasswordChanged(sender As Object, e As RoutedEventArgs)
    If pwBox.Password = "Password" Then
        statusText.Text = "'Password' is not allowed as a password."
    End If
End Sub

Here's the result when this code runs and the user enters "Password".

In Windows Store apps, the PasswordBox has a built-in button that the user can touch or click to display the password text. Here's the result of the user's action. When the user releases it, the password is automatically hidden again.

In Windows Phone Store apps, the PasswordBox has a built-in checkbox below it that the user can check to display the password text.

RichEditBox

You can use a RichEditBox control to enter and edit rich text documents that contain formatted text, hyperlinks, and images. You can make a RichEditBox read-only by setting its IsReadOnly property to true.

By default, the RichEditBox supports spell checking. To disable the spell checker, set the IsSpellCheckEnabled property to false. For more info, see Guidelines and checklist for spell checking.

You use the Document property of the RichEditBox to get its content. The content of a RichEditBox is a Windows.UI.Text.ITextDocument object, unlike the RichTextBlock control, which uses Windows.UI.Xaml.Documents.Block objects as its content. The ITextDocument interface provides a way to load and save the document to a stream, retrieve text ranges, get the active selection, undo and redo changes, set default formatting attributes, and so on.

This example shows how to load and save a Rich Text Format (rtf) file in a RichEditBox.

<Grid Margin="120">
    <Grid.RowDefinitions>
        <RowDefinition Height="50"/>
        <RowDefinition/>
    </Grid.RowDefinitions>
    <StackPanel Orientation="Horizontal">
        <Button Content="Open file" Click="OpenButton_Click"/>
        <Button Content="Save file" Click="SaveButton_Click"/>
    </StackPanel>
            
    <RichEditBox x:Name="editor" Grid.Row="1"/>
</Grid>
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)
    {
        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);
    }
}

private async void SaveButton_Click(object sender, RoutedEventArgs e)
{
    if (((ApplicationView.Value != ApplicationViewState.Snapped) ||
          ApplicationView.TryUnsnap()))
    {
        FileSavePicker savePicker = new FileSavePicker();
        savePicker.SuggestedStartLocation = 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";

        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.
            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.
            FileUpdateStatus status = await CachedFileManager.CompleteUpdatesAsync(file);
            if (status != FileUpdateStatus.Complete)
            {
                Windows.UI.Popups.MessageDialog errorBox =
                    new Windows.UI.Popups.MessageDialog("File " + file.Name + " couldn't be saved.");
                await errorBox.ShowAsync();
            }
        }
    }
}

Using the touch keyboard

The touch keyboard can be used for text entry when your app runs on a device with a touch screen. The touch keyboard is invoked when the user taps on an editable input field, such as a TextBox or PasswordBox, and is dismissed when the input field loses focus. The touch keyboard uses accessibility info to determine when it is invoked and dismissed. The text controls provided in the XAML framework have the automation properties built in. If you create your own custom text controls, you must implement TextPattern to use the touch keyboard.

Summary and next steps

You learned how to create TextBox, PasswordBox, and RichEditBox controls to display and edit text in your app.

For more code examples that show these controls, see the XAML text editing sample.

Guidelines and checklist for text input

Guidelines and checklist for spell checking

Roadmap for Windows Runtime apps using C# or Visual Basic

Roadmap for Windows Runtime apps using C++