What’s New in Silverlight 5? - Control and Text Improvements


Introduction

In this article, we'll have a brief discussion of the new features of controls and text in Silverlight 5.

Overview

Silverlight 5 has undergone few improvements in controls and text; new added features for controls, and rendering and performance enhancements for text.

The following are the new features of controls in Silverlight 5:

  • Text tracking and leading control
  • Text overflow
  • Multi-click support
  • Type-ahead text searching
  • SaveFileDialog DefaultFilename
  • DataContextChanged event (not in Beta)

And text has been improved in in a few ways:

  • Rendering is now better
  • Performance of text layout has been improved
  • Text clarity is improved with Pixel Snapping
  • OpenType support has been enhanced

As improvements in text were all about rendering and performance, we won't talk more about the text improvements. Instead, we'll focus in this article on control stack and cover the changes that happened to it in details.

Text Tracking and Leading Control

Silverlight 5 has added three features to text controls (TextBlock, TextBox, and RichTextBox) to allow you to control precisely text tracking and leading space for characters and lines:

  • Character Spacing
  • Line Height
  • Line Stacking Strategy

Character Spacing

This feature allows you to precisely set how far apart each character is. This feature is available in all text controls through a property called CharacterSpacing that specifies the distance between characters. This distance is measured by 1000th of the current font size, means that for instance if you set the font size to 20px and character spacing to 500, then the distance will be 10px between each character (since 20 * 500 / 1000 = 10px.)

Here's an example of a TextBlock that uses the character spacing feature to put 10px between each character:

<TextBlock FontSize="20" CharacterSpacing="500">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</TextBlock>

Silverlight1.png

Line Height

This feature allows you to set precisely the height of each line of the content in a text controls. It's available in all text controls through a property called LineHeight and, unlike CharacterSpacing, it's measured in pixels.

The following code sets the height of each line in the text to 50px:

<TextBlock Margin="5" LineHeight="50">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
<LineBreak />
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
<LineBreak />
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</TextBlock>

Silverlight1.1.png

Line Stacking Strategy

This feature allows you to specify how each line box is determined. For example, if you're in a scenario like the following where you have some text larger than other text, what will you do?  Would you increase the height for each line to accommodate the size for the larger text and allow the text to be readable?  Or would you leave the text as it as if there wasn't any text with different font size? That's what the stacking strategy is all about.

<TextBlock Margin="25" FontSize="12">
Lorem ipsum <Span FontSize="20">dolor sit amet</Span>, ...
<LineBreak />
Proin aliquam augue quis ipsum <Span FontSize="38">rhoncus</Span> ...
<LineBreak />
Quisque eleifend ante vitae velit vehicula luctus. ...
</TextBlock>

Silverlight2.png

The stacking strategy is available to your code through a new property called LineStackingStrategy. This property takes one value of three:

  • MaxHeight (default):

    Increases the size of each line's box enough to hold its content. If LineHeight is set, adds the value of LineHeight to the determined value of the height of line's box.
     
  • BlockLineHeight:

    Uses value from LineHeight if specified. Otherwise, increases the size for each line's box to hold its various font sizes content.
     
  • BaselineToBaseline:

    Uses value from LineHeight if sepified. Otherwise, uses the default line height that doesn't care about whether the content has larger text or not.

The following figure compares between the three stacking strategies while setting LineHeight and while not setting it.

Silverlight3.png

Makes sense?

Text Overflow

This feature allows for multi-column and free-form text layouts. It's available for RichTextBoxes only. You set a RichTextBox as the master element, and link it to the new RichTextBoxOverflow to capture extra text that doesn't fit in the master RichTextBox. You can also continue the chain and link another RichTextBoxOverflow to the previous one to capture extra text that doesn't fit there and so on. To link an overflow control to another one, you use the new OverflowContentTarget property available in the previous control to bind to the next overflow control.

The following figure shows how you can use overflow controls to create multi-column text:

Silverlight4.png

And the following shows an example of a free-form text where the text wraps around an object in the center:

Silverlight5.png

The following example creates a multi-column text:

<Grid.ColumnDefinitions>
  <ColumnDefinition />
 <ColumnDefinition
/>
<ColumnDefinition />
</Grid.ColumnDefinitions>

<RichTextBox OverflowContentTarget="{Binding ElementName=firstOverflow}" />

<RichTextBoxOverflow x:Name="firstOverflow" Grid.Column="1"
OverflowContentTarget="{Binding ElementName=secondOverflow}"/>

<RichTextBoxOverflow x:Name="secondOverflow" Grid.Column="2" />

Multi-Click Support

Silverlight 5 now allows you to capture multi-clicks in controls. It can capture any n-clicks, but most of the time you'll capture double-clicks and sometimes triple clicks. This feature is available through a property called ClickCount available in MouseButtonEventArgs. While MouseButtonEventArgs is available in ButtonDown and ButtonUp events, ClickCount is only valid on MouseLeftButtonDown and MouseRightButtonDown, it always return 1 from ButtonUp events.

The following code shows how you can capture multiple clicks in a TextBlock, it updates the TextBlock for each click:

        private void theTextBlock_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (e.ClickCount == 1)
                theTextBlock.Text += "Single-click\n";
            else if (e.ClickCount == 2)
                theTextBlock.Text += "Double-clicks\n";
            else if (e.ClickCount == 3)
                theTextBlock.Text += "Triple-clicks\n";
            else
                theTextBlock.Text += e.ClickCount.ToString() + "\n";
        }

Type-Ahead Text Searching

Type-ahead text searching capability in Silverlight 5 allows you to search in a collection control (e.g. ComboBox, ListBox, etc.) using keyboard; you reach the desired item by typing the first letters of its content.

The content that the control searches in must be specified in DisplayMemberPath. For example, in our books scenario to search in book titles you must set DisplayMemberPath to the Title field. This leads up to another problem, if you have set a data template, you cannot set DisplayMemberPath along with it. This problem can be solved by using the new Silverlight 5 XAML feature, implicit data templates, which has been covered earlier in the previous article.

In our books scenario, we have the following ComboBox that has an implicit data template applied:

<ComboBox x:Name="books" />

And we have also the following code that populates the ComboBox and sets the DisplayMemberPath to allow searching using keyboard:

 books.ItemsSource = new BookData().OrderBy(b => b.Title);
 books.DisplayMemberPath = "Title";

The application works perfectly now. But if you convert the data template to an explicit data template like the following:

<ComboBox x:Name="books>
<ComboBox.ItemTemplate>
<
DataTemplate>
<
StackPanel>
<
TextBlock Text="{Binding Title}" FontWeight="Bold" />
<TextBlock Text="{Binding Author}" />
<TextBlock Text="{Binding Price, StringFormat='C'}" />
</StackPanel>
</
DataTemplate>
</
ComboBox.ItemTemplate>
</
ComboBox>

You receive the following error, because DisplayMemberPath cannot be set while setting an ItemTemplate:

Silverlight6.png

SaveFileDialog DefaultFilename

Now in Silverlight 5 you can set the default filename in SaveFileDialog (using the new DefaultFileName property) that will show in the file name box when you launch the dialog:

 SaveFileDialog dialog = new SaveFileDialog();
 dialog.DefaultFileName = "Foo";
 dialog.ShowDialog();

Silverlight7.png

DataContextChanged Event

This feature is currently not available in Beta; it should be available in the final version. It occurs when the DataContext object for a control changes.

Summary

For controls in Silverlight 5, we have the following improvements:

  • Text tracking and leading control:
    Allows you to set character spacing, line height, and line stacking strategy for a text control.
  • Text overflow:
    Available for RichTextBoxes. Allows for multi-column and free-form text layouts.
  • Multi-click support:
    Allows you to capture any n-clicks.
  • Type-ahead text searching:
    Allows searching in a collection control using keyboard.
  • SaveFileDialog DefaultFilename:
    Allows you to set the default file name for SaveFileDialog.
  • DataContextChanged event:
    Not in beta. Occurs when the DataContext object for a control changes.

And in the text stack, there were some improvements related to performance and rendering:

  • Rendering is now better
  • Performance of text layout has been improved
  • Text clarity is improved with Pixel Snapping
  • OpenType support has been enhanced


Similar Articles