Pages

Monday, March 26, 2012

A WPF Technique: Decorating controls by deriving from standard control

I always consider StackPanel as Vertical StackPanel as it is Vertical by default, but why there is no layout control that is horizontal by default?. I believe it does not worth for the WPF framework to introduce one as it is very easy to write if you need one. In this post I am going to describe how easy is to create a HorizontalStackPanel and a couple of related useful notes.

Define types by deriving from WPF controls.
The simplest way to write your own controls is to derive from existing ones. You do not need to do anything else. Yes, that it, you have the same control with the same functionalities but with a different Type. For example you may derive a class from TextBlock, it still is a TextBlock but it has its own specific type, so it is behave in a slightly different in some cases, mostly when you refer the types like in a TargetType of a Style.
Here is a summary of benefits of doing so:
  • Defining some common behaviour in code and not using the styles
  • Easier targeting them in styles
  • More readable XAML code
  • Very helpful for code sharing between Silverlight and WPF
HorizontalStackPanel as an example
For example you may define a HorizontalStackPanel by deriving a type from StackPanel and setting its Orientation to Horizontal in its constructor. Actually it is not a horizontal stackpanel but it is InitialyHorizontalStackPanel as the users have the opportunity to change the orientation later using XAML or code.
Also the HorizontalAlignment in StackPanel has a default value of Stretch, you need to set it back to Left and do the same for VerticalAlignment.


public class Horizontal : StackPanel
{
    public Horizontal()
    {
        Orientation = Orientation.Horizontal;
    }
}
public class Vertical : StackPanel
{
    public Vertical()
    {
        Orientation = Orientation.Vertical;
    }
}


So now you can write these XAML code

<StackPanel>
  <StackPanel Orientation="Horizontal">
      
  </StackPanel>
</StackPanel>

This way

<s:Vertical>
  <s:Horizontal>
      
  </s:Horizontal>
</s:Vertical>

Which is much more readable and less cluttered.


No comments:

Post a Comment