Silverlight 4 Rough Notes: RichTextArea

Note – these posts are put together after a short time with Silverlight 4 as a way of providing pointers to some of the new features that Silverlight 4 has to offer. I’m posting these from the PDC as Silverlight 4 is announced for the first time so please bear that in mind when working through these posts.

Silverlight 4 has a much richer way of displaying “documents” in that it provides a RichTextArea control. In some ways this is analogous to a lightweight version of the document support in WPF.

There’s a new System.Windows.Documents namespace which contains classes such as;

  • Paragraph
  • Hyperlink
  • Inline
  • InlineUIContainer
  • LineBreak
  • Run
  • Span

from which you can construct pretty rich documents for display in the RichTextArea. The RichTextArea has a content property called Blocks which is a collection of Block ( which have alignment ) which looks to translate into on concrete type of Paragraph right now. A Paragraph has a collection of Inlines which can be Span, InlineUIContainer, Run, LineBreak, Hyperlink ( there may be more, my exploration stopped there ).

This means that I can put together a document for display in a RichTextArea;

<UserControl
    x:Class="SilverlightApplication27.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300"
    d:DesignWidth="400">

    <Grid
        x:Name="LayoutRoot"
        Background="White">
        <RichTextArea
            TextWrapping="Wrap"
            IsReadOnly="False">
            <Paragraph>The quick brown fox jumped over the lazy dog</Paragraph>
            <Paragraph
                TextDecorations="Underline"
                FontSize="24"
                TextAlignment="Right"
                FontFamily="Courier New">The quick brown fox jumped over the lazy dog
            </Paragraph>
            <Paragraph>
                The quick brown fox jumped over the lazy dog
                <LineBreak />
                The quick brown fox jumped over the lazy dog
                <LineBreak />
                <Italic>
                The quick brown fox jumped over the lazy dog    
                </Italic>
            </Paragraph>
            <Paragraph>
                The quick brown fox jumped over the lazy dog
                <InlineUIContainer>
                    <Rectangle
                        Margin="2"
                        Fill="Red"
                        Width="48"
                        Height="12" />
                </InlineUIContainer>with a red rectangle
            </Paragraph>
            <Paragraph>
                <Hyperlink
                    NavigateUri="http://www.microsoft.com"
                    TargetName="">Go to Microsoft.com</Hyperlink>
            </Paragraph>
            <Paragraph>
                <Run
                    Text="The quick brown " />
                <Run >fox jumped over the lazy dog</Run>
            </Paragraph>
            <Paragraph>
                <Span FontSize="24">
                    <Run>The quick brown fox jumped over the lazy dog</Run>
                    <Run>The quick brown fox jumped over the lazy dog</Run>
                </Span>
            </Paragraph>
        </RichTextArea>
    </Grid>
</UserControl>

where you can see some of Paragraph, Span, Run, Hyperlink, InlineUIContainer and one or two others being exercised a little. Of all of those, InlineUIContainer perhaps deserves special call out as it allows me to embed arbitrary UI into the document.

This gives me a UI;

image

and this isn’t read-only, I can wander into the UI and start to edit the content;

image

and even delete that red rectangle when I come to it with the cursor. There’s also a level of undo/redo support in there.

Now, naturally, all of what has been created in XAML is programmable from code that I put behind of that UI so all of those types like Paragraph, Run etc. can be coded against and animated, bound and so on ( at least where the types/properties allow binding, animation ).

We can also put other Silverlight elements into those InlineUIContainer elements so if I add something simple like a Button;

<UserControl
    x:Class="SilverlightApplication27.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300"
    d:DesignWidth="400">

    <Grid
        x:Name="LayoutRoot"
        Background="White">
        <RichTextArea
            TextWrapping="Wrap"
            IsReadOnly="False">
            <Paragraph>
                This is some text and then there's a piece of UI
                <LineBreak />
                <InlineUIContainer>
                    <Button
                        Content="Click Me" 
                        Click="Button_Click"/>
                </InlineUIContainer>
                <LineBreak />
                and then there's some more text and some space for more still;
                <LineBreak />
                <Run
                    x:Name="runToModify" />
            </Paragraph>
        </RichTextArea>
    </Grid>
</UserControl>

then, with these default settings the Button will show up but is disabled because the RichTextArea is in editable mode. If I move it to read-only mode;

    <RichTextArea
            TextWrapping="Wrap"
            IsReadOnly="True">

then the Button becomes usable and with some code behind;

  public partial class MainPage : UserControl
  {
    public MainPage()
    {
      InitializeComponent();      
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
      runToModify.Text = "dynamically added some more text";
    }
  }

does exactly what you’d expect it to do when I click the Button – adds the extra text;

image

There’s a bunch of events on the control such as TextInputEvent, TextInputStartEvent, TextInputUpdateEvent and there’s also a Selection property that you can grab hold of.

I suspect there’s a lot more reading to do on this one but it’s great to have a lot more flexibility around the display of text and to then go beyond that by allowing for rich user interface elements to be embedded into that display.

It does raise some interesting questions though because I can see scenarios where you could use UI elements containing text or a RichTextArea containing UI elements to present the same data and I guess it’ll take some time to figure out which approach is “best” in different situations.