Earlier I explored some options to allow inline hyperlinks in Silverlight 3 using some extensions and the WrapPanel
. In Silverlight 4, which was released as beta earlier this week, the problem is solved in the framework. Silverlight 4 gives us the RichTextArea
control, which allows us to organize runs, spans, paragraphs, and even embed other UI elements to create a very richly illustrated document.
To illustrate this, I fired up a new Silverlight Application in Visual Studio 2010 and chose a Silverlight 4 application. Grabbing some more "lorem ipsum" text, I threw it into a RichTextArea
control and then began embellishing with hyper links, formatting, and tossed in a red rectangle for good measure. The markup looks like this:
<RichTextArea TextWrapping="Wrap"> <RichTextArea.Blocks> <Paragraph>Lorem ipsum dolor sit amet consectetur adipiscing elit. <Bold>Suspendisse eu erat quis nibh laoreet hendrerit.</Bold> <Italic>Tortor quam, auctor vel elementum et, rhoncus id augue.</Italic> <Span Foreground="BlueViolet">Vestibulum nulla augue, dictum ut placerat et,</Span> <Span>hendrerit a lorem. Vestibulum ante ipsum primis in</Span> <Hyperlink NavigateUri="http://www.wintellect.com/"> faucibus orci luctus </Hyperlink> <Run>et ultrices posuere cubilia Curae; Donec sollicitudin feugiat augue, eu vestibulum eros dapibus vel. </Run> <InlineUIContainer> <Rectangle Width="20" Height="20" Stroke="Black" Fill="Red"/> </InlineUIContainer> Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. </Paragraph> </RichTextArea.Blocks> </RichTextArea>
As you can see, I am able to mix raw text, spans and runs that format colors or fonts, hyperlinks, and even use the InlineUIContainer
to toss a rectangle into the mix. After building and publishing, this is what appears in the browser:
As you can see, a very serviceable rendering!
Next, we'll have a quick bit of fun. I add some row definitions and a header:
<Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <TextBlock FontWeight="Bold" Grid.Row="0">Header
I wire the text area into row 1, then add this button to the last row:
<Button Click="Button_Click" Content="Print" Grid.Row="2"/>
Do you get where I'm going? We don't want to print the header or the button, just the lorem ipsum section, so this is what we wire into the code behind:
public partial class MainPage : UserControl { PrintDocument _pd; public MainPage() { InitializeComponent(); _pd = new PrintDocument(); _pd.PrintPage += new EventHandler(pd_PrintPage); } void pd_PrintPage(object sender, PrintPageEventArgs e) { e.PageVisual = MainText; } private void Button_Click(object sender, RoutedEventArgs e) { _pd.DocumentName = "Lorem Ipsum"; _pd.Print(); } }
Note that we have three steps:
- Create a printing surface
- Trigger the print by calling the print method (and optionally setting some parameters)
- Wiring into the print event and setting the visual to print only what we want (keep in mind we could have created an entirely new set of UI elements here).
The new page looks like this:
When I click "print" I'm given the familiar print dialog. I selected the XPS writer and saved it as an XPS document. Here is the final result:
I'll continue to follow how Silverlight 4 makes our life easier by integrating into the framework what we used to have to build ourselves!