Easy as Pie: Percentage Pie-Charts with the Expression Blend 4 Pie Shape

Now, with the new Pie Shape in Expression Blends 4 this has become a no-brainer. Here’s how.

During the evolution of Silverlight and Expression Blend we’ve had to create Pie Charts for various projects. Often these were to illustrate the state of a percentage value in the application. Thus we’ve build our own a few times over. Now, with the new Pie Shape in Expression Blends 4 this has become a no-brainer. Here´s how:

 PieShape01  PieShape02 

  1. Create a new Silverlight Application project in Blend 4
  2. Open the Asset Panel and select the Shapes category
  3. Select the Pie Shape
  4. DoubleClick the Pie Shape at the bottom of the ToolBox so it is added to the Artboard with default values of StartAngle 90 and EndAngle 360
  5. Name it Pie1 in the Objects and Timeline panel. This way you can use code to access its properties.
  6. If you want you can give it a Fill Color to see it better.
  7. Add an event handler called UpdateArcEndAngle on the MouseLeftButtonUp event of the LayoutRoot Grid.
  8. In the Code Behind file (MainPage.xaml.cs) add a line of code to update the StartAngle of the Arc:private void UpdateArcStartAngle(object sender, MouseButtonEventArgs e)
    {
        Pie1.StartAngle += 45;
    }
  9. Build the project and click the Pie to update it with 45 degrees each time you click it. When the Pie has reached the 360 degrees, it with start again at 45.

Of course, you can style a Pie Shape any way you want. Now it is easier than ever to show a percentage Pie Chart…

 Pie01  Pie02

 Pie03

Njoy!

Focus on FocusVisualElement in Silverlight buttons

The FocusVisualElement is the equivalent of the dotted line that you see in Windows interfaces and on browser pages around an object on the page that “has the focus”. This means that it will receive the input a user is giving with a mouse, keyboard or touch. Actually, web designers don’t really like these dotted lines, because they degrade the look of their interface. It may disturb the carefully crafted look and feel of the page. But this FocusVisualElement has a function.

Normally I’m not so eager to use buttons as controls for showing examples. It usually doesn’t lead to an interesting visual result. As a designer my examples should look more interesting. Fortunately in Silverlight you can create other shaped and colored buttons easily using the Make into Control… option in the contextmenu of graphic elements gathered in a Grid. In this case the I’d like to focus on the FocusVisualElement element, so Buttons are my first choice.

In Silverlight the FocusVisualElement is an actual graphical element that is part of a control’s ControlTemplate. In Blend you can access this template by selecting Edit Template/Edit Current (I’d really like a keyboard shortcut here, but there isn’t, yet).

In template editing mode you can find the FocusVisualElement in every Silverlight control. It’s shape depends on the type of control, but in a Button it is a light blue Rectangle. By default this Rectangle has its Opacity set to Zero and the Focused State makes it visible. This leads to the notion that you can change the looks of this Focused State to anything you’d like:

UnFocused

  LinkFocused

ButtonFocused2  ButtonFocused

In these images I show how a HyperlinkButton could get a Glow Effect when it is focused. But there’s no reason to leave it at that. The oval Button plays an animation when it is focused. Apart from the Opacity, a TranslationX, Scale and a PointAnimation is applied to a semitransparent Ellipse when the Focused State is triggered. This makes the Ellipse move van left to right. The animation is AutoReversed and repeated Forever.

You can use the VisualStateManager to create the animations. You can also show the TimeLine and create an Storyboard that you paste in de <VisualState x:Name="Focused" /> Visual State. When you create a Button using Make into Control… you can copy the Visual States out of the ControlTemplate of a normal Button and use them in your own.

Make sure your animation for the Focused State of controls are low-key. You don’t want to irritate your users with flashing graphics only because a control is focused!

Working code from these Buttons is on my SkyDrive

Njoy!

Overlapping TabItems with the Silverlight Toolkit TabControl

OverlappingTabs

Standard TabItems are not overlapping, but designers like them to. You may encounter a design with overlapping tabs that you have to create and implement. This is not a simple task, certainly when the tabs have a tapered side that overlaps the tab to the right of it. The Z-Index of these tabs are opposite to the standard layout.

Control Vendors have custom versions of a TabControl, that use properties for overlap. The Toolkit TabControl currently doesn’t support overlapping tabs, but by updating templates and a bit of C# code you can get the same effect. Here’s how it’s done:

Creating an overlapping tab in Expression Design:

OverlappingTabsCreate01

  1. Start Design, start a new file with a size of 640 x 480 pixels.
  2. Add a rectangle, 50 pixels wide, 25 pixels high and make its CornerRadius 3 pixels. Make sure the Rectangle is selected.
  3. Choose Object. Convert Object to Path. This way you can change the vertices of the shape.
  4. Select the Direct Selection tool (second from the top in the Toolbox) and select the bottom right two vertices by dragging a selection area around them.
  5. Drag the two vertices to the right, about half the width of the rectangle. Hold the Shift key to constrain the translation horizontally.
  6. Zoom in to the right hand side of the shape. With the Pen Tool selected, at the right bottom corner delete the second vertice from the bottom by clicking on it.
  7. Hold the Alt Key and click the other vertice to make it a rounded point (fig. 1).
  8. Select the Direct Select Tool and move the second vertice from the top to the right. Select the Pen Tool, hold the Alt Key and drag from this anchor point in the direction of the line of the tab, so the sharp corner becomes smooth.
  9. Using the Direct Selection Tool, move the left vertice at the left bottom corner down to the bottom of the tab, delete the other by clicking on it with the Pen Tool selected (fig. 3).

OverlappingTabsCreate02

figure 1: Create a round point at the bottom right corner.

OverlappingTabsCreate03

figure 2: Create a smooth corner at the top right corner.

OverlappingTabsCreate04

figure 3: Remove a anchor point to create a straight corner at the lower left corner.

Double click the Magnifying Glass Icon at the bottom of the toolbox to show the entire drawing. It helps to place the top right corner of the tab at the 0,0 coordinates using the Action Bar at the bottom of the screen. Check if the Foreground color is white and the border is black. Make sure the tab is selected, showing its bounding box and transformation handles, and select Edit, Copy from the menu.

Implementing overlapping tabs in Expression Blend:

  1. Start Blend, Begin a new Silverlight project, Open MainPage.xaml.
  2. Open the Asset Panel, enter Tab in the search box, select TabControl and drag a rectangle on the Artboard. You’ll get a TabControl with two tabs. A reference to System.Windows.Controls.dll is added to the project references and a namespace xmlns:controls is added to your MainPage.xaml file.
  3. The TabControl is a container for the TabItems. It has a four Grids to place tabs on all sides of the tab area. Tabitems are placed in these grids. The TabItems consist of a Header and a Grid as you can see in the Object and Timeline Panel when a tab is selected. Right click a Tab and select Edit Template, Edit a Copy… from the context menu, choose a name and a location for the ControlTemplate and click OK.

OverlappingTabsImplement01

figure 4. Creating a TabItem ControlTemplate

  1. You’ll enter Template Editing Mode for the TabItem. The Objects and Timeline panel shows eight grids and a FocusVisualElement Border. For each of the four sides (Top, Bottom, Left, Right) you’ll see a Selected and a Unselected Part. Control Parts are recognizable by the green icon next to their name. You can also find them in the Parts Panel.
  2. Locate the TemplateTopSelected Grid in the Object and Timeline Panel and open all the borders and grids that are part of it by clicking the small triangles in from of it. Drag the ContentControl named HeaderTopSelected up to the TemplateTopSelected Grid so it moves to the same hierarchical level. Now you can delete the rest of the content of the TemplateTopSelected Grid. Also delete all the animations that reference those shapes if they are not deleted by Blend.
  3. With this Grid selected, choose Paste from the edit menu. This will place the tab you created in Expression Design into the grid. Remove its Margins to make the tab fit inside the Grid.
  4. Drag the layer of the new Path up so it is placed right beneath the TemplateTopSelected Grid and above the Focus and Disabled visuals in the Objects and Timeline Panel. Move the HeaderTopSelected Content Control beneath the Path.
  5. Repeat Step 3 and 4 for the TemplateTopUnselected Grid. Make its Foreground a slightly darker color than the selected state of the tab.
  6. Set for both the TemplateTopSelected as the TemplateTopUnselected Grid the left margin to –20 pixels. This will ruin the bounding box placing in Blend, but move the tabs to the left at runtime.
  7. Make sure the Grid for the selected state of the tab has a Path at the bottom, that makes the connection with the tab area beneath it. It is important that a tab connects to the area that shows when a tab is selected.
  8. You may want to delete the FocusVisualTop border because it is rectangular and your tabs are not. Also remove any animations targeting this control.
  9. Scope up to the Control Level using the breadcrumbs at the top of the screen or the Return Scope to [UserControl] button at the top of the Objects and Timeline Panel.
  10. Right Click the TabControl and Select Edit Additional Templates, Edit Layout of Items [ItemPanel], Create New. Make sure it is a StackPanel with its Orientation set to Horizontal. Scope up to the Control Level.
  11. Right Click the TabControl (not a tab) and Select Edit Template, Edit a Copy… Give the System_Windows_Controls_Primitives:TabPanel a left margin of 20, but leave the other margins as they are: margin=”20,2,2,-1″ compensating for the negative left margin on the first TabItem.
  12. Use the Visual State Manager to create a state for a MouseOver that is a light gray between the selected and unselected Foreground colors. A transition time of half a second gives the right effect.

        <controls:TabControl x:Name=”TabControl” Width=”500″ Height=”100″
             Style=”{StaticResource TabControlStyle1}”
             ItemsPanel=”{StaticResource ItemsPanelTemplate1}”
             SelectionChanged=”TabControl_SelectionChanged”>
            <controls:TabItem x:Name=”Tab_1″ Header=”Tab 1″
                 Style=”{StaticResource TabItemStyle1}”>
                <Grid Background=”#FFE5E5E5″>
                    <TextBlock Text=”Area 1″ Margin=”20″/>
                </Grid>
            </controls:TabItem>
            <controls:TabItem x:Name=”Tab_2″ Header=”Tab 2″ 
                Style=”{StaticResource TabItemStyle1}”> 
                <Grid Background=”#FFE5E5E5″>
                    <TextBlock Text=”Area 2″ Margin=”20″/>
                </Grid>
            </controls:TabItem>
            <controls:TabItem x:Name=”Tab_3″ Header=”Tab 3″
                 Style=”{StaticResource TabItemStyle1}”>
                 <Grid Background=”#FFE5E5E5″>
                      <TextBlock Text=”Area 3″ Margin=”20″/>
                 </Grid>
            </controls:TabItem>
            <controls:TabItem x:Name=”Tab_4″ Header=”Tab 4″
                 Style=”{StaticResource TabItemStyle1}”>
                 <Grid Background=”#FFE5E5E5″>
                     <TextBlock Text=”Area 4″ Margin=”20″/>
                 </Grid>
            </controls:TabItem>
        </controls:TabControl>

Getting the ZIndex right

All this will create the right shape and states of the the TabControl, but the order of the tabs is still wrong. By default the first tab is selected and a right tab will overlap a left tab. With overlapping tabs this should be the other way around. Setting the Canvas.ZIndex property of the TabItems in XAML won’t help. The control is initialized with the wrong settings at runtime.

A little C# helps. Thanks to Rachel, who solved this problem in WPF, we can set the overlapping tabs in the right order when the SelectionChanged event of the TabControl is fired:

private void TabControl_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)

    TabControl tabControl = sender as TabControl; 
    tabControl.Dispatcher.BeginInvoke( new Action(() =>
            UpdateZIndex(sender as TabControl)));
}

private void UpdateZIndex(TabControl tc)

    if (tc != null)
    {
        foreach (TabItem tabItem in tc.Items)
        {
            tabItem.SetValue(
                        Canvas.ZIndexProperty,
                        (tabItem == tc.SelectedItem ?
                        tc.Items.Count :
                        (tc.Items.Count-1) – tc.Items.IndexOf(tabItem)));
        }
    }
}

The UpdateZIndex method is invoked in a way that updates all the TabItems. This way a left tab will show above a right tab the way you want in overlapping TabItems.

OverlappingTabs

fig 5. Overlapping tabs have a reversed ZIndex.

Working code is at my SkyDrive

Joe Gershgorin has refactored the code to use a Behavior. This also supp0rts longer text in the headers. You can find his version at: http://www.bitspy.com/OverlappingTabs_Silverlight4.zip

Njoy!

QuoteFloat: Animating TextBlock PlaneProjections for a spiraling effect in Silverlight

[silverlight: http://members.chello.nl/s.dol/QuoteFloat.html]

QuoteFloat is an animation for TextBlock elements, inspired by the way the HTC Touch HD shows SMS Text messages. It moves the text up and rotates it at the same time resulting in a spiraling effect. It is done by giving the TextBlock elements a PlaneProjection each and animating the RotationY and GlobalOffsetY properties.

The TextBlock elements are positioned below the bottom of the Canvas. The Canvas has a Clipping Mask so no one will see them until the animation starts. The XAML looks like this:

[sourcecode language=”XML”]
<Canvas x:Name="cvsBg" Width="500" Height="155"
Clip="M0.5,0.5 L499.5,0.5 L499.5,154.5 L0.5,154.5 z">
<TextBlock x:Name="txt1" Text="Txt1" Canvas.Top="192"
Style="{StaticResource TextBlockStyle1}">
<TextBlock.Projection><PlaneProjection/></TextBlock.Projection>
</TextBlock>
    <TextBlock x:Name="txt2" Text="Txt2" Canvas.Top="228"
     Style="{StaticResource TextBlockStyle1}">
     <TextBlock.Projection><PlaneProjection/></TextBlock.Projection>
</TextBlock>
    <TextBlock x:Name="txt3" Text="Txt3" Canvas.Top="265"
    Style="{StaticResource TextBlockStyle2}">
    <TextBlock.Projection><PlaneProjection/></TextBlock.Projection>
    </TextBlock>
</Canvas>
[/sourcecode]

I use two Styles for the two TextBlocks. Notice the second style is BasedOn, so it needs only to define the properties that are different from the first style. The Canvas.Top property is different for all the TextBlocks and defined inline in the XAML above.

[sourcecode language=”XML”]
<Style x:Key="TextBlockStyle1" TargetType="TextBlock">
    <Setter Property="Foreground" Value="White"/>
    <Setter Property="Width" Value="400"/>
    <Setter Property="Height" Value="25"/>
    <Setter Property="FontSize" Value="21.333"/>
    <Setter Property="FontFamily" Value="Trebuchet MS"/>
    <Setter Property="TextAlignment" Value="Center"/>
    <Setter Property="Canvas.Left" Value="50"/>
</Style>
<Style x:Key="TextBlockStyle2" TargetType="TextBlock"
    BasedOn="{StaticResource TextBlockStyle1}">
    <Setter Property="FontSize" Value="14"/>
    <Setter Property="Canvas.Left" Value="200"/>
</Style>
[/sourcecode]

The actual animations are quite repetative, being almost the same for all TextBlock elements. The crucial word here is almost: the animations differ for .2 seconds. Stopping the text is the natural result from easing out and the easing in the animation.

QuoteFloatStoryboard

[sourcecode language=”XML”]<Storyboard x:Name="QuoteFloat" RepeatBehavior="Forever">
    <DoubleAnimationUsingKeyFrames
        BeginTime="00:00:00" Storyboard.TargetName="txt1"
        Storyboard.TargetProperty=
            "(UIElement.Projection).(PlaneProjection.RotationY)">
        <EasingDoubleKeyFrame KeyTime="00:00:00" Value="90"/>
        <EasingDoubleKeyFrame KeyTime="00:00:01.5" Value="0">
            <EasingDoubleKeyFrame.EasingFunction>
                <CubicEase EasingMode="EaseOut"/>
            </EasingDoubleKeyFrame.EasingFunction>
        </EasingDoubleKeyFrame>
        <EasingDoubleKeyFrame KeyTime="00:00:03" Value="-90">
            <EasingDoubleKeyFrame.EasingFunction>
                <CubicEase EasingMode="EaseIn"/>
            </EasingDoubleKeyFrame.EasingFunction>
        </EasingDoubleKeyFrame>
… more animations

    <DoubleAnimationUsingKeyFrames
        BeginTime="00:00:00"
        Storyboard.TargetName="txt2"
        Storyboard.TargetProperty=
            "(UIElement.Projection).(PlaneProjection.RotationY)">
        <EasingDoubleKeyFrame KeyTime="00:00:00.2" Value="90"/>
        <EasingDoubleKeyFrame KeyTime="00:00:01.7" Value="0">
            <EasingDoubleKeyFrame.EasingFunction>
                <CubicEase EasingMode="EaseOut"/>
            </EasingDoubleKeyFrame.EasingFunction>
        </EasingDoubleKeyFrame>
        <EasingDoubleKeyFrame KeyTime="00:00:03.2" Value="-90">
            <EasingDoubleKeyFrame.EasingFunction>
                <CubicEase EasingMode="EaseIn"/>
            </EasingDoubleKeyFrame.EasingFunction>
        </EasingDoubleKeyFrame>
… more animations

[/sourcecode]

The text was not set using code, but in Blend. It then uses a DiscreteObjectKeyFrame for the TextBlock Text property and uses the given String Value.

[sourcecode language=”XML”]
   <ObjectAnimationUsingKeyFrames
BeginTime="00:00:00"
Storyboard.TargetName="txt1"
Storyboard.TargetProperty="(TextBlock.Text)">
     <DiscreteObjectKeyFrame KeyTime="00:00:00" Value="Technology requires design"/>
     <DiscreteObjectKeyFrame KeyTime="00:00:03" Value="Imagine users as very intelligent"/>
     <DiscreteObjectKeyFrame KeyTime="00:00:06" Value="No matter how cool you interface is,"/>
     <DiscreteObjectKeyFrame KeyTime="00:00:09" Value="Significant change"/>
   </ObjectAnimationUsingKeyFrames>
[/sourcecode]

The Loaded event of the UserControl is used to start the animation in the MainPage CodeBehind file:

[sourcecode language=”XML”]
<UserControl x:Class="QuoteFloat.MainPage"
    xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation
    xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml
    Width="500" Height="155" Loaded="StartAnim">
[/sourcecode]

 

[sourcecode language=”XML”]

private void StartAnim(object sender, System.Windows.RoutedEventArgs e)
{
    QuoteFloat.Begin();
}

[/sourcecode]

Complete Blend project is on my SkyDrive…

Njoy!

Silverlight Togglebutton Push Pin Style with IsoStore

Now you can pin a full-screen app to a second monitor in Silverlight 4, you may want an UI control to facilitate this. In fact, what you need is a ToggleButton. And your ToggleButton has to be communicate it’s function. A Push Pin Style is a good solution for that.

This Push Pin Style for a silverlight (or WPF) ToggleButton is small, totally customizable and free :). It features tooltips to show the action you can do. The setting is stored in IsoStore and picked up the next time you start your app. The states are each represented using a canvas, so you can easily swap the visuals for your own if you want to.

PushPin

The XAML is simple:

<ToggleButton x:Name="btnPin" Style="{StaticResource btnPin}" Checked="pin" Unchecked="unpin" Content="" ToolTipService.ToolTip="Pin this"/>

Files are too large to include here, but I put the project on my SkyDrive.

Njoy!

Mix Keynote bij Microsoft NL

Ik had het voorrecht om te gast te zijn bij de presentatie van de keynote bij Microsoft Nederland. De hoofdpersoon van de avond was Windows Phone 7 series. Alle kennis die je als developer of designer hebt opgedaan over Silverlight kan je 100% inzetten voor het maken van applicaties voor WP7. Alle gereedschappen om Windows Phone 7 apps te maken zijn gratis beschikbaar. De ontwikkelsoftware is beschikbaar via developer.windowsphone.com. Dank Microsoft NL voor een geslaagde avond.

Ik had het voorrecht om te gast te zijn bij de presentatie van de keynote bij Microsoft Nederland. In combinatie met de SDN had de Silverlight en Expression Insiders usergroup een aantal plaatsen te vergeven. Mensen die zich ingeschreven hebben op Sixin.nl hebben een e-mail gehad met een link naar het inschrijvingsformulier voor het evenement. Ze hebben een ochtend de tijd gehad om zich in te schrijven.

Uiteindelijk waren er zo’n dertig mensen vanuit verschillende gebruikersgroepen en invalshoeken naar het nieuwe Microsoft hoofdkwartier gekomen om de aftrap van de MIX 2010 op een groot scherm in een grote vergaderzaal mee te maken. Er waren drankjes en borrelhapjes, maar zodra de videostream op gang was gekomen was iedereen ademloos aan het luisteren en kijken. In sneltreinvaart zijn verschillende mensen en evenzoveel verschillende demo’s aan het oog voorbijgekomen. Enkele opmerkelijke feiten heb ik via Twitter kunnen verspreiden, totdat mijn telefoon het opgaf omdat hij te lang had aangestaan.

De tweets gingen over de 60% marktpenetratie van Silverlight (in Nederland 72%), de mogelijkheid om fullscreen Silverlight video te kijken op een tweede (of derde) scherm, Silverlight als techniek achter Pivot, Blend 4 als gratis update voor Blend 3, dat e-bay een appstore heeft waar Silverlight apps verkocht kunnen worden en dat Silverlight 4 vandaag Release Candidate is geworden. De RTW wordt eind april verwacht, waarschijnlijk gelijk met Visual Studio 2010.

Maar de nadruk van de keynote van MIX10 lag niet op Silverlight en niet op de Expression tools. De hoofdpersoon van de avond was Windows Phone 7 series, met een uitgebreide demonstratie van de mogelijkheden van de telefoon, inclusief verschillende typen applicaties, door Joe Belfiore. ScottGu bouwde ter plekke de eerste Twitterclient voor WP7 en een collega van hem maakte binnen 8 minuten een foto-applicatie in Expression Blend 4. De Silverlight versie op WP7 is geen Silverlight lite of aparte Silverlightversie. Het is gewoon Silverlight. Alle kennis die je als developer of designer hebt opgedaan over Silverlight kan je 100% inzetten voor het maken van applicaties voor WP7. Er worden in sneltreinvaart een aantal games getoond die gemaakt zijn in XNA en gespeeld op de telefoon, de computer met de muis en een televisie met een XBox controller. Als je apps of games op WP7 wilt krijgen gaat dat via de Marketplace hub. Exacte voorwaarden worden later nader bekend gemaakt. Alle gereedschappen om Windows Phone 7 apps te maken zijn gratis beschikbaar. De ontwikkelsoftware is beschikbaar via developer.windowsphone.com.

Na de presentatie was er tijd om even bij te praten over de nieuwe mogelijkheden. Daarna was er een live verbinding met een aantal Nederlandse bezoekers van MIX10 en de mogelijkheid om vragen te stellen en beantwoord te krijgen. In het restaurant van het Microsoft gebouw kwamen pizza’s en drankjes beschikbaar, die onder begeleiding van stevige discussies zijn verorberd. Dank Microsoft NL voor een geslaagde avond. Thuis de bits downloaden en installeren en aan de slag voor Windows Phone 7 Series met Silverlight…

ScreenMachine in Silverlight Showcase

It took a while, but my personal porftolio in Silverlight called ScreenMachine, has appeared in The Silverlight showcase. You can also reach it through the ADdendum blog, too. When you select The Netherlands as Geography in the left menu of the Showcase you can find it as fourth on the first row (for now).

ScreenMachineInShowCaseSmall Njoy!

Edit Oct 2011: The new url for the Screenmachine is :

http://www.silverlight.net/showcase/2009/10/screenmachine

It is placed in the News Category and it is on the 16th page or

in th Silverlight 4 Category on page 61…

Top 10 Silverlight 4 beta features for Designers

Silverlight 4 beta is out and delivers several new features for programmers, media people and designers. As a designer I was most interested in some specific features, so I’d like to share my top 10 with you.

10. Command property on buttons and hyperlink

I’ll have to explain this one. John Papa’s whitepaper only speaks of the MVVM pattern context, but in the WPF world commands are well known. Actually it is a feature not unlike Behaviors, because they encapsulate programming code in a simple property on a button or a hyperlink. The action that follows when clicking that button or hyperlink is determined by the command. Also, it is possible to include a parameter that the command can use. Thus it is used more dynamically and is more flexible. When developers create commands, designers can easily connect them as a simple property of a button or hyperlinkbutton.

<Button Content="Load" Width="120"
        Command="{Binding LoadProductsCommand}"
        CommandParameter="{Binding Path=Text, ElementName=MyFilterTextBox}"/>

9. StringFormat, TargetNullValue, FallbackValue on Data Binding

Again, maybe not straightforward, but these additions to the data binding functionality of Silverlight helps designer to format the results of data binding with more ease. TargetNullValue will show a value when the binding has null as a result, so you can insert a zero or other sensible value instead. The FallBackValue is about the same, but it shows up when a binding is unsuccessful. You can apply a different value instead. The best of the three is the StringFormat property, which allows you to format the text resulting from data binding. This way a designer can easily indicate that output is a currency or a percentage or a date in a specific format.

<TextBox Text="{Binding Path=UnitPrice, Mode=TwoWay, StringFormat=C}" />

<TextBox Text="{Binding Path=Discount, Mode=TwoWay, StringFormat=P}"/>

<TextBox Text="{Binding Path=OrderDate, Mode=TwoWay, StringFormat=’MM-dd-yyyy’}"/>

8.Webbrowser control and HTML brush

This seems like a nobrainer, but some restrictions are present. This only works in sandboxed applications, which means that you have to have an Out-Of-Browser application. You can use inline HTML (NavigateToString), an inline HTML document (Navigate) or an URL (Source).

string html = "<HTML><HEAD></HEAD><BODY style=’margin:0 padding:0′><IFRAME width=’100%’ style=’overflow: hidden;’ height=’100%’ src=’http://www.microsoft.com’ /></BODY></HTML>";

HtmlContent.Navigate(html)

The HTML brush lets you paint with a webpage, so you can use it as a Brush in any Shape.

<Path Data="…" >

    <Path.Fill>

        <HtmlBrush x:Name="htmlBrush" AlignmentX="Left" AlignmentY="Top" Stretch="None"/>

    </Path.Fill>

</Path>

And in C# set the source: htmlBrush.SetSource(MyWebBrowser);

7. CompositeTransform

This makes a designers’ live a bit easier: combine Translation, Rotation and Scale in one go:

<Rectangle Height="100" Width="100" Fill="Red">
    <Rectangle.RenderTransform>

        <CompositeTransform ScaleX="2" Rotation="45" TranslateY="42"/>

    </Rectangle.RenderTransform>

</Rectangle>

6. Webcam and Microphone support

This one is self-explaining, but… What are designers and developers going to do with it? Check out the blog-post by Rob Houweling on the Silverlight and Expression Insiders site for details about this feature.

5. Rich Text Area control

Finally a way to create richer text experiences using the Rich Text Area. This will end the struggle with Run elements in TextBlocks to change a color, font or font size inside a text object. The Rich Text Area control welcomes every type of content. This includes other controls like Images and UI controls. Create bold, italic, colored text inside a block of text with ease using the Rich Text Area control. Will this lead to the inclusion of FlowDocuments in Silverlight one day?

4. ViewBox

A ViewBox is a handy container that allows you to scale up or down any graphic or large element that you want to display on a screen. Use the original sizes for the content and set the ViewBox to the size you want the content to show up. It’s that easy and very convenient at times. A ViewBox can contain only one element inside. It’s StretchDirection can be UpOnly, DownOnly or Both. The content can be Stretch-ed using None, Fill, Uniform and Uniform to fill, just like it’s WPF version.

<Viewbox x:Name=”iconSize” Margin="5" Width="64" Height="64">

    <Image Source="aHugeImage.png"/>

</Viewbox>

3. Fluid UI States for ItemsControl

I’d be very interested to see what designers and developer create with this feature. Create an ItemsControl and hook up interesting appearing and disappearing animations when adding or deleting items from the control. This not only allows you to animate ListBoxItems with ease, but opens the door to exiting navigation using items in ItemControls. Who’s up for the challenge? The new visual states are: BeforeLoaded, Loaded, and Unloaded.

2. Implicit Style

Styling an application helps in acceptance and defining a look for different groups of users. Implicit Styles will help a lot in implementing Themes. Actually the ToolKit people have already removed the Implicit Style Manager that took care of this. Just omit the x:Key and all controls of a the specific type will take on the style you give them. Combined with swapping ResourceDictionaries you have theming solutions available.

1. Printing support

Even though it is only possible in code, printing support is a huge improvement from a designers’ point of view. This is the most requested feature for a reason. It is possible the print the content of a page using the LayoutRoot, or any other container that you specify. It is also possible to print objects that are entirely invisible on the screen, but you’ll have to build a tree of objects in memory a feed that to the print command. This opens up enough possibilities to satisfy business consumers. So output your work to printers everywhere…

PrintDocument pd = new PrintDocument();

pd.PrintPage += (s, args) => {

    args.PageVisual = LayoutRoot;

};

pd.Print();

These are the features that caught my eye as a designer. Some didn’t make it to the top ten, like the WordEllipsis TextTrimming property, Right Mouse Click Events and ScrollWheel events and ClipBoard support. Other features are more interesting for media people or developers. Check out Tim Heuer’s blog or John Papa’s white paper for all details on all new Silverlight 4 features.

Njoy!

Silverlight Style: GlassBorderStyle

GlassBorderStyleCreated a simple, but nice Glass Border for a panel in my current Silverlight 3 project. I’d like to share it with you…

 

 

 

 

 

  <Style x:Key="GlassBorderStyle" TargetType="Border">
    <Setter Property="BorderThickness" Value="2"/>
    <Setter Property="Padding" Value="5"/>
    <Setter Property="Background">
        <Setter.Value>
            <LinearGradientBrush EndPoint="0.75,1" StartPoint="0.25,0">
                <GradientStop Color="#33FFFFFF" Offset="0"/>
                <GradientStop Color="#C0FFFFFF" Offset="0.287"/>
                <GradientStop Color="#4011322D" Offset="0.683"/>
                <GradientStop Color="#33FFFFFF" Offset="1"/>
            </LinearGradientBrush>
        </Setter.Value>
    </Setter>
    <Setter Property="BorderBrush">
        <Setter.Value>
            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                <GradientStop Color="#5811322D" Offset="0"/>
                <GradientStop Color="#3EFFFFFF" Offset="0.25"/>
                <GradientStop Color="#FFFFFFFF" Offset="0.5"/>
                <GradientStop Color="#3EFFFFFF" Offset="0.75"/>
                <GradientStop Color="#BFFFFFFF" Offset="1"/>
            </LinearGradientBrush>
        </Setter.Value>
    </Setter>
    <Setter Property="Effect">
        <Setter.Value>
            <DropShadowEffect BlurRadius="3" ShadowDepth="3" Opacity="0.5"/>
        </Setter.Value>
    </Setter>
</Style>

To use this style:

<Border x:Name="GlassBorder" Height="100" Width="100" CornerRadius="10"
    Style="{StaticResource GlassBorderStyle}">
    <Button Content="OK"/>
</Border>

Njoy!

Use initParams to swap ResourceDictionaries and load a Theme in Silverlight 3

I’ve been looking for a way the use themes just swapping ResourceDictionaries (RD’s) for some time. Now, with Silverlight 3 being able to use MergedDictionaries, this becomes possible.

It is Blendable, but you can only use RD’s with Build Action Resource and not Content. This is annoying enough to give it another go another time. You can use the workaround of using a the RD’s with build action as Resource for use with Blend only. You’ll have to change it back before you distribute your app. Want you ultimately want is to address the RD’s as Resource…

This method can help you when you:

  • want to load a theme once on application startup
  • want to set the theme as an initParam on the Silverlight plug-in
  • don’t want to use implicit styling: you’ll need two or more RD’s with identically named Styles and Resources

Restrictions of this method are:

  • Blendable using workarounds
  • You have to use one Default theme (which can have any name you want).
  • You cannot dynamically update the theme: you can set a certain theme only once at application startup.

If this is the method for you, this is what you need to do:

  • Create ResourceDictionaries for the Default theme and for one or more other themes that you want to load in the root of your Silverlight project.
  • Use x:Keys for Styles and Resources and keep them the same between RD’s.
  • Set the Build Action for these RD’s to CONTENT in Visual Studio or by editing your .CSPROJ file by hand.
  • Insert an initParam in the <Object> tag in your startup file like this:

[sourcecode language=”XML”]

<param name="initParams" value="Theme=TheTheme" />
[/sourcecode]

  • Add a Default MergedDictionary in App.xaml:

[sourcecode language=”XML”]

<Application.Resources> 
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Default.xaml"/>
        </ResourceDictionary.MergedDictionaries>

[/sourcecode]

  • Declare a private currentTheme variable in App.xaml.cs

[sourcecode language=”XML”]

public partial class App : Application
{
    private string currentTheme = "Default";
    …

[/sourcecode]

  • Set the Default theme, get the initParam, make an URL to the filename and create and RD from that. Then add the RD to the MergedDictionaries:

[sourcecode language=”XML”]

private void Application_Startup(object sender, StartupEventArgs e)
{

    //set the current theme to the currentTheme variable
    string currentThemeName = string.Format("{0}.xaml", currentTheme);

    //get the theme name from the initParam
    string themeParameter = e.InitParams["Theme"];

    if (!string.IsNullOrEmpty(currentThemeName))
    { 
        //set the current theme to the theme parameter and create filename
        currentThemeName = string.Format("{0}.xaml", themeParameter);

        //create an URL from the currentThemeName
        Uri themeUrl = new Uri(currentThemeName, UriKind.RelativeOrAbsolute);

        try
        {
            //create a RD and set the source to the URL
            ResourceDictionary themeDictionary = new ResourceDictionary
            {
                Source = themeUrl
            };

            //Add the RD as a MergedDictionary
            Application.Current.Resources.MergedDictionaries.Add(themeDictionary);
        }
        catch (Exception ex)
        { 
            //communicate theme doesn’t exist
            throw; 
        } 
    }

    this.RootVisual = new MainPage();

}

[/sourcecode]

Many thanks to Tony Tromp and Michaud Venant for helping me out with the code.

The error “Error HRESULT E_FAIL has been returned from a call to a COM component” occurs when you forgot to change the build properties of the ResourceDictionaries to CONTENT. You can do this in Visual Studio in de Solution Explorer with the properties of the specific XAML files. This error also occurs when you maken a mistake in the name of the Theme in the initParam by messing up the quotes for example.

When you make a mistake in the Styles or the Resources used by the Styles you’ll get another error: Cannot find a Resource with the Name/Key AppBg [Line: y Position: x]. Actually if the style is OK in the Default theme it wil show that. Happily this error is easier to track and to fix, but a small error in your RD’s may have unpredictable results, so make sure they are sound.

I’ve been working with Themes from initParams for weeks. You can use Blend when you set the build action in VS to RESOURCE and restart Blend. Blend should show all the RD’s as Resources in the Resources Panel and you can edit them in the Blend artboard. You can even build in Blend and change the Theme using the initParam in the startup file. Make sure the startupfiles are the same in VS and Blend :). Before you deliver your project make sure you set the build action back to CONTENT in VS to make the theme system from initParams kick in.

I’ve placed working code on my SkyDrive.

Njoy!