Setting Complex Properties in WPF

In the last tutorial, we learnt how to create a simple WPF application using visual studio, how to add controls to the XAML and how to set properties to them (remember height and width of button?). The properties we set in the tutorial were, however, of simple value type. Not all properties are of simple value types. Some properties are made up of multiple objects, which might themselves have multiple properties, which might again have objects…you get the idea! These are complex type properties and setting them is slightly more complex too.

Let us consider the case of “Background” property on the Button control.

The Background property is an example of a property of complex type. You can of course set it similar to how you would set a simple type:

<Button x:Name=”button” Width=”100″ Height=”90″ Content=”Click me” Background=”Blue”/>

Instead of saying “Blue”, you could also use the hexadecimal code for it ”#FF0000FF”. In either case, you will get a button with a blue background. However, you could also, set the complex property type using property element syntax. In this case, you set the value for a complex type by setting values for its objects. You can do this by using child elements as shown:

<Button>
<Button.Background>
<SolidColorBrush Color=”Blue” Opacity=”10″>
</Button.Background>
</Button>

In the above code, Background is the complex property type and you are using it as a child element or property element and setting its content. As you can see, the content is of type “SolidColorBrush” which is a complex type with multiple properties itself. The syntax for using property element syntax is always <ClassName.PropertyName>. You can extend this even further by again using SolidColorBrush as a child or property element to set the values at a more minute level (AGBY in this case) as shown:

<Button.Background>
<SolidColorBrush>
<SolidColorBrush.Color>
<Color A=”100″ R=”0″ G=”0″ B=”255″ />
</SolidColorBrush.Color>
</SolidColorBrush>
</Button.Background>

When you run this code, this is what you will see:

WPF2_4

Admittedly, the use of property elements makes the code quite cumbersome as compared to direct setting of attributes but sometimes it is the only way when you want something specific, say some exact shade of blue which you achieve through trial and error. It is also useful when you want to change some specific aspect of a property dynamically during runtime, say the value of “A” in the above scenario. In this case, instead of binding the entire attribute to runtime behavior, you can instead bind the value of A to produce the desired effect. We will see this in a slider program in a forthcoming tutorial.

All that said, as a thumb rule, remember that the simpler the code, the better it is. So do not use too many property elements unless it is absolutely necessary.

Setting Content
In the previous tutorial, we learnt that “Content” is a special type of property that can be set explicitly or implicitly by using it as a child element: <Button>Click Me</Button>

The interesting thing here is that content is of type object, and this means that you are not restricted to setting it to text alone. You can set it to images, shapes and much more. For instance, say we want to have a square inside a button. You can do this by setting the content to a rectangle using the property element syntax:

<Button x:Name=”button” Width=”100″ Height=”90″ Background=”Blue”>
<Rectangle Width=”24″ Height=”24″ Fill=”Yellow” />
</Button>

When you run this, you will see a yellow square inside your button:

WPF2_5

If you don’t give the property name (for example background), then the child element is assumed to be content. You can set the content only once for an element.

The above trick is commonly used when a button has an image instead of actual content. For example, you may want to have the “+” image inside a button that allows users to add items to a list. You can do it by placing the image as the button content.

Markup Extensions
Sometimes, there are situations when simple setting of a property is not enough, even when you use property element syntax. For example, say you wanted all the buttons in your application to have a yellow square inside them. This becomes quite tedious if you do it individually for each button. Imagine if you want to change something (say color of square) for all buttons; you would require you to make the change for each and every button. To avoid this, we use what is known as a “markup extension”. What you do is essentially store the value in the application’s resources, give it a key and use this lookup key to set the attribute. To set the attribute using the lookup key, you use markup extensions. These are enclosed within curly braces {} and the braces are a mark of markup extensions. Within the braces, you specify the type of extension followed by optional named parameters. So, for the above button example, you would typically create a resource, call it “mybutton”, and link it to the attribute using markup extensions (with mybutton as the lookup key). To create a resource, you use:

<Window.Resources>
<Rectangle x:Key=”mybutton” Width=”24″ Height=”24″ Fill=”Yellow”></Rectangle>
</Window.Resources>

Now, wherever you want to use this resource, you simply use a markup extension with the “mybutton” key for looking it up:

<Button Content=”{StaticResource mybutton}”>

This gives the same result as the earlier case where we set the content as a rectangle using property element syntax. Now, changing the color of the button is a simple matter of changing it once within the resource and it gets reflected wherever you have used the StaticResource markup with mybutton lookup. StaticResource is the extension that is used by WPF to retrieve values from an application’s resources using some lookup key. The value of a staticresource cannot change during runtime. You can have more than one named parameter for a markup extension. You just separate it out using commas: {ExtensionName Param1=Value1, Param2=Value2, Param3=Value3}

Note: Remember not to have quotation marks around values or whitespaces otherwise you will get a parser error.

Apart from StaticResource, there are many other kinds of markup extensions such as Binding, DynamicResource, RelativeSource, x:Null, x:Type, x:Array, x:Static etc. All of them will be handled in forthcoming tutorials.

In the next tutorial, we will make a simple FontViewer program that will allow us to see the fonts installed on your system. With it, you will begin actual programming in WPF applications.

Leave a Reply

Your email address will not be published. Required fields are marked *


+ 2 = nine

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>