Friday, June 05, 2009

Background Color of TextBlock in Silverlight 2

In a WPF application (as of .NET 3.5) you can set the background color for a text block as follows:
<TextBlock ... Background="Red" ...> </TextBlock>
Despite being correct Silverlight 2 doesn't like this XAML code. Trying to set it programmatically leads to an exception. Therefore a different solution is needed. Here is what works in my case. I use a Canvas and place a Rectangle and a TextBlock inside of that Canvas. Unless you set the ZIndex use this order so that the TextBlock is in front of the Rectangle. I use the Rectangle as the background for the TextBlock. When the TextBlock changes its size I update the size of the Rectangle accordingly. This solution is pretty simple in the end. First the XAML code:
<UserControl x:Class="Foo.LabelWithBackground"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             Width="200" Height="20">
   <Canvas>
      <Rectangle Name="_labelBackground" Width="20" Height="20"
                 Fill="LightSkyBlue"/></Rectangle>
      <StackPanel>
         <TextBlock Height="20" HorizontalAlignment="Left" Name="_label"
                    VerticalAlignment="Center" Padding="4,2,4,0" 
                    Text="The Label Text" MinWidth="20"></TextBlock>
      </StackPanel>
   </Canvas>
</UserControl>
Next the C# code-behind:
public partial class LabelWithBackground : UserControl {
   public LabelWithBackground() {
      InitializeComponent();
      _label.SizeChanged += LabelSizeChanged;
   }

   void LabelSizeChanged(object sender, SizeChangedEventArgs e) {
      _labelBackground.Width = _label.ActualWidth + 
                       _label.Padding.Left + _label.Padding.Right;
   }
}
Of course you can use this UserControl in either a page (Silverlight) or in a window (WPF). In both cases you will get a label with background.
Check out my blog on Agile Leadership

Thursday, June 04, 2009

WPF and Silverlight: Sharing User Controls

Both WPF and Silverlight share XAML as the language to describe the layout, look and feel of a user interface. So I thought. There are differences, though, at least for .NET 3.5 and Silverlight 2. And the differences are not only limited to the XAML code but also to the code-behind regardless of whether you use C# or any other .NET language. Sure I did know that Silverlight doesn't support 3D graphics (at the moment) and so I didn't expect those to work. I'm also aware that Silverlight has a Visual Style Manager that is not available in WPF. And the root element in Silverlight is a Page while in WPF it is a Window. And Silverlight is more than just the UI part since it also represents a minimum CLR runtime environment and not a full .NET 3.5 implementation. So my expectations were along those lines. But I discovered more beyond my expectations. Small, yet sufficient differences that makes it hard to share UI components between WPF-based and Silverlight-based applications. And that's what I'd like to do since I want to leave the choice between using a native user interface and a rich internet application (RIA) to my customers. To reduce the gap I'm using I'm using components from the Silverlight tool kit that are in the "stable" band. Otherwise I wouldn't have available components such as TreeView. One example of a noticeable different is that in WPF a TextBlock can have an attribute named "Background" while in Silverlight you will get a parse error of you try to render the XAML code. There are also inconsistencies (or differences) in terms of how mouse events are handled. For instance the set of PreviewMouse* functions that are available in WPF don't exist in Silverlight 2. If you want to use Hittest() in your code-behind it won't work (or even compile) in Silverlight. Instead you have to use functionality of the VisualTreeHelper class. There are quite a few of these difference at the moment and I'll provide more details as I discover them along with code examples. My hope, though, is that over time the differences between the two are reduced at least for the features they have in common. It's pretty annoying that setting the background color is different between WPF and Silverlight. It's also pretty annoying that finding a component at a mouse cursor position is different. Maybe .NET 4.0 and Silverlight 3 are a step towards easier sharing of user controls. The community would love to see that!
Check out my blog on Agile Leadership.