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>
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>
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>
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.
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:
And the following shows an example of a
free-form text where the text wraps around an object in the center:
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:
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();
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