Saturday, 11 May 2013

Markup Extension | WPF Tutorial pdf

Now as you know about TypeConverter, let us take MarkupExtension into account.
Markup Extensions gives the flexibility to create custom objects into your XAML attributes. Every markup extension is enclosed within a {} braces. Thus anything written within the Curl braces will be taken as Markup Extension. Thus XAML parser treats anything within the curl braces not as literal string and rather it tries to find the actual MarkupExtension corresponding to the name specified within the Curl braces.

Exception :
If you want to put braces within a string you need to put {} at the beginning to make it an exception.
You can read "How to Escape {} in XAML" for more information.

Example of Markup Extension :
<TextBox Text={x:Null} />
Probably the simplest of all, it actually a MarkupExtension which returns Null to the Text string.

There are already few Markup Extensions defined with XAML defined within  System.Windows.Markup namespace which helps every time to produce functional features within your XAML. Let us discuss few of them :

NullExtension
This is the most simple MarkupExtension we ever have. It actually returns Null when placed against a value.
Example :
Content = "{x:Null}"

ArrayExtension
This is used to create an ArrayList of items. The x:Array actually returns an object of Array of type specified.
Values = {x:Array Type=sys:String}

StaticExtension
Another simple Extension which returns Static field or Property references.
Text="{x:Static Member=local:MyClass.StaticProperty}"
Thus when you define a static property StaticProperty for MyClass, you will automatically set the value to Text property using this.

TypeExtension
Type extension is used to get Types from objects. When the attribute of a control takes the Type object you can use it.
TargetType="{x:Type Button}"
So TargetType receives a Type object of Button.

Reference
It is used to Refer an object declared somewhere in XAML by its name. It is introduced with .NET 4.0
Text="{x:Reference Name=Myobject}"

StaticResourceExtension
Resources are objects that are defined within the XAML. StaticResource substitutes the key assigned to the object and replaces its reference to the Resource element declared.
<Grid.Resources>
<Color x:Key="rKeyBlack">Black</Color>
<SolidColorBrush Color="{StaticResource rKeyBlack}" x:Key="rKeyBlackBrush"/>
</Grid.Resources>
<TextBlock Background="{StaticResource ResourceKey=rKeyBlackBrush}" />
StaticResource errors out if the key is not there during compile time.

DynamicResourceExtension
This is same as StaticResource, but it defers the value to be a runtime reference.
Thus you can declare any key for a DynamicResource and it should be present during runtime when the actual object is created.
<TextBlock Background="{DynamicResource ResourceKey=rKeyBlackBrush}" />
Now the rKeyBlackBrush if not declared as Grid.Resources will not error out. You can add that during Runtime when Window Loads.

What are Resources ?
Resources are objects that are created the object is rendered by XAML parser. Every Framework Element object has a ResourceDictionary object placed within it. You can add Resources within this ResourceDictionary and can reuse those component within the scope.
Resources are reusable component which one can use for several times to produce its output. So if you need an object that you want to reuse more than once in your application, and you don't want the object to be changed within the scope, Resources are then the best option for you.
<Grid.Resources>
<Color x:Key="rKeyRed">Red</Color>
<Color x:Key="rKeyCyan">Cyan</Color>
<LinearGradientBrush x:Key="rKeyforegroundGradient">
<GradientStop Color="{StaticResource rKeyRed}"
Offset="0"></GradientStop>
<GradientStop Color="{StaticResource rKeyCyan}"
Offset="1"></GradientStop>
</LinearGradientBrush>
</Grid.Resources>
<TextBlock Text="{Binding ElementName=cGeoPoint, Path=GeoPointValue}"
FontSize="30" Margin="50" Grid.Row="1" Grid.ColumnSpan="2"
Foreground="{StaticResource rKeyforegroundGradient}" />

So you can see we have defined a LinearGradientBrush and used as Foreground of the TextBlock. This object can be reused any time when required.
Every FrameworkElement has a property called Resource which takes an object of Resource Dictionary. You can assign various resources to this Collection which you would use in different object created within the scope of the object. In XAML, resources are declared using x:Key attribute, and later this key can be used to refer to the resource in ResourceDictionary using StaticResource or DynamicResource.

Difference between StaticResource and DynamicResource
StaticResource finds the key defined within the ResourceDictionary under its scope during the Loading of the application. Hence the Compiler will throw error during compilation if not found in resources. On the other hand, DynamicResource Markup Extension defers the resource assignment to the actual runtime of the application. So the expression remains unevaluated until the object being created.

Note : If the resource is derived from Freezable (immutable), any change to the object will change the UI regardless of whether it is a StaticResource or DynamicResource.

Example : Brush, Animation, Geometry objects are Freezable.
Choice between StaticResource and DynamicResource
=> StaticResource requires less CPU during runtime, so it is faster.
=> StaticResource are created when the application loads. So making everything as StaticResource means slowing down the Application Load process.
=> When the resources are unknown during compilation, you can use DynamicResource. DynamicResource are used when user interaction changes the look and feel of an object.
=> DynamicResource is best when you want your resource to be pluggable. You can read how to create pluggable resources from : Pluggable styles and Resources.

No comments: