In this section we will have a look at how we can reuse resources, templates, xamls, custom elements and custom controls.

Resource System

The first way of making UI reusable is using the Resource System provided by WPF. But this approach cannot be used at all the places because it is not supported for UI elements. We can define UI elements in the resource but if we use it more than one place we will get an error as the resource system will refer to the same underline object. So this approach will be useful where we can reuse the objects itself. So this approach is perfect for Freezeable as the types which derive from freezable are shareable. For example if we have a logo which needs to be shown at multiple places then we can define it as a resource and reuse it.

*A freezable object has two states – frozen and unfrozen. When an object is frozen, it cannot be modified and it cannot even fires events but the unfrozen state, it works same as a normal object.

There is a trick which works in compiled xaml scenarios can be used to define reusable framework elements. We use the compiled XAML’s deferred loading to give each resource reference a new copy. As in compiled xaml the Resource Dictionaries are loaded on demand. This won’t work if this xaml is parsed at runtime.

Let’s see this in action. Add the following code to your window. The resource that we see here has x:Shared to false. When you are typing this xaml you will not find this appearing in intellisense . The reason is because Microsoft has hidden it and it might go away in the future versions. Using this False value will help us share the component because it specifies that the object should not be shared and each element using this should have its own copy. Normally what happens when we ask for a resource what WPF does is it creates an instance of it and keeps it in handy and when some other objects asks for it WPF provides the same object reference. But as we have turned off the sharing of the resource WPF will not keep the reference of the object in memory and when another object asks for this reference then WPF creates a new one and give it to the object. This won’t work for parsing xaml.

 

WPF Resource System

WPF Resource System

When we run this we will see that we have two buttons using the same resource. It would just work for simple static resources.

Templates

Templates are designed as a mechanism to reuse the trees of object that include user interface elements or behaviors. The event handlers that we define in the templates will be hooked to the object each time it is instantiated. Templates are usually declared as resources and it is a shared object. A template is just a factory and each time we use it creates a new copy and gives it the object. Templates are usually defined to work in a particular context like the ControlTemplate works to define the look of a particular control and a Data Template will work to display the data in the specified format. To use the template in a particular format we need to use the raw template. Let’s see this in action. Add the following code to your WPF window and you will see that we have specified a ControlTemplate in the Window.Resources. We have instantiated the ControlTemplate with the help of the Control Base class. As Control is the base for all Controls and it introduces the concept of Templates in the Controls and it’s not abstract. A control does not have any intrinsic behavior so we have used it as a way to host the template. It is not the perfect way of using the template though. As you can see we have specified that the controls should not act as a focus control. If we do not turn off the Focusable then each of these controls will have focus twice.

 

WPF Templates

WPF Templates

Another way of fixing this double focus issue is by using a DataTemplate and a ContentPresenter. Add the code as shown below to a Winow xaml.

 

WPF Templates

WPF Templates

The best place to use data templates is when the situation demands it such as DataBinding or ControlCustomization.

Xaml File Reuse

We can also reuse the xaml by separating it out to a different file and we can use Application.LoadComponent to load the compiled xaml resources. The Application.LoadComponent creates a new object by reparsing the xaml or baml every time it is called. After loading the component we need to add it to the UI tree. The root of the xaml file can be any type and we can package any sub tree this way.

We can also use a Frame or a NavigationWindow to load the xaml. It’s really straight forward to load   the xaml this way. All we need to do is point Frame directly to xaml file in the project and it will load a copy of the page. We can only point these to a xaml file whose root is a Page.

Xaml with Code Behind

In our application we can combine any xaml file with a code behind file. All we need to do is to provide the x:Class attribute which will define the code-behind class and we can use any WPF type as the root.

Let’s see this in action. Let’s create a reusable Grid with some behavior. Add the following xaml to a Page.

 

WPF Xaml + Code Behind

WPF Xaml + Code Behind

Now add the following code to the code behind of the GridComponent.

 

WPF Xaml + Code Behind

WPF Xaml + Code Behind

Now let’s try use this GridComponent which has a Button Click behavior,

 

WPF Xaml + Code Behind

WPF Xaml + Code Behind

Anytime we are defining classes with code behind, we are just creating partial classes and we can instantiate them with C# new operator or we can use xaml as shown above.

UserControl

UserControl is name of the reusable UI component which is built from other components. As we saw in the last section that we derived from a Grid to create a custom control, generally in WPF we derive from UserControl. You should know that UserControl does not do a lot. We can take an approach similar to user control with any UI element. The main reason of the existence of UserControl is to have a recognizable base class. The only problem with using Grid as the base class instead of the UserControl is that the .NET programmers will expect the Grid base class to provide the same functionality a Grid does and that might be really messy because the Grid will break the rule that the derived class provides the same functionality as the base class. As a matter of fact the UserControl also breaks the rule of derived class. The UserControl derives form Control but still it does not provide the functionality for a Template because there is no way to hook up the look of the UserControl with the code behind. User Controls are not lookless controls. UserControl is derived from ContentControl. It does that because whatever control you put inside UserControl xaml it displays that. This means if we set the content of the UserControl then the complete content of the UserControl will be replaced. So we should not try to set its template or Content.

Limitation – A class only gets to use xaml once in its inheritance chain. Although we can inherit from UserControl, we cannot use the xaml because the UserControl base class has already used it and same is true if the class derives from Window or Page. A class gets to use xaml with code behind only once and the base class has already done that then we cannot do it again. To understand this you will need to understand how Application.LoadComponent works. The way it hooks up xaml with code-behind is incompatible with inheritance. There are two things that need to be hooked up at xaml loading time.

  • Named elements must be placed in their corresponding fields.
  • Event handlers that specified its attributes must be attached.

Application.LoadComponent does this by using the interface IComponentConnector. The code behind class implements this. So when the derived class tries to implement the IComponentConnector then its implementation replaces the one that was done by the base class.

Runtime XAML Parsing

We can generate and parse xaml at runtime. For example we have an application that returns xml documents then we might have to run these through xslt which will generate the xaml and we would parse and run this xaml. This parsing can be done through the xaml reader class. We can do this by passing the xaml string or by passing xamlReader object and it will return an object with the root as the xaml tree and that tree will be defined as the xaml passed. The restriction in this mode is that events will work. Also we will need to call the FrameworkElement.FindNamed helper method to find any named components.

Custom Elements

Here are a few base classes that do not involve xaml:

  • Decorator – It is the base class for all the utility elements that contain a single child and provides some sort of service. The exact functionality of the decorators varies from a decorator to decorator. The border decorator provides the border around the child element whereas a viewbox applies a scale transform on the child so that the child takes all the space. A decorator and content control both host a child. The difference between them is that a Content Contol has some interactive behavior whereas a decorator does not.
  • Adorner – Adorners are visual elements that are attached to some other elements that always appear on top. As we can see in the image below that one of the grids is selected and all the resize, rotate, etc options available are all adorners. These adorners will be visible even when the object’s z-index in low and its not visible on the screen.

 

WPF Adorner

WPF Adorner

But an adorner decorator is the one which decides the bound of the adorner. So even when the element is sent back then also adorner is visible so you would think that an adorner is designed to be on the top at all times but when a panel comes above it as shown in the image below the adorner does not come above it. This is done with the help of an adorner decorator in the visual tree. S here an adorner decorator is defined as the parent of the design surface so that no adorner comes above it.

 

WPF Adorner

WPF Adorner

  • Panel – Panel is the base class for the WPF layout strategy type i.e. Grid, StackPanel,etc. If we want to write a custom layout we need to derive from Panel.
  • Shape – This is the base class to use when building any custom shape like a rectangle or ellipse. It provides Fill, Geometry cache, etc properties.
  • FrameworkElement – This is the base class to use when we are building a Code based user interface element and there is no other base class that suits our needs.

Custom Controls – This used when our UI elements has some distinctive behavior which is not provided by the controls available.

API Considerations

While building a custom control or a custom feature we need to consider the following things.

  • Properties – These are useful for components that are reusable from xaml as this is the API that does not require code and the functionality of the control will be accessible simply by setting properties. To use properties we need to use the WPF’s dependency property system so that the property supports Triggers, Animation, styling, data binding, notifications, etc.  So there might be properties that do not do a lot in code but are controlled by the templates.

 

  • Events – These allow code to be run when things happen in your code. These also allow triggers to be hooked up into xaml. Defining a custom event is pretty similar to defining a property. We need to register the event and store in a public static read only field.

 

We provide event accessor. The AddHandler and RemoveHandler methods are provided by the FrameworkElement base class.

 

We need to raise the event by creating a RoutedEventArgs and passing it into the FrameworkElement ReiseEvent method. RaiseEvent requires the event to be of type RoutedEventsArgs or derived from that.

 

We can add a class level event handler for the built in events.

  • Commands– These are really useful in controlling the behavior of the elements as any operations that can invoked by commands can be driven by xaml. We can hook up controls like menu item or a button with commands. Commands are really straight forward. We just need to create a Command of type RoutedUICommand and provide a name, display name and owning type. Commands are made available as public static read only fields.

 

In order for a command to do something we need to register a command Binding. As we want each and every instance of the class to handle the command we should use a class level command binding instead of the instance level binding as the class level binding is slightly more efficient. To register the command we need to pass the static command name and command owner details to the CommandManager.RegiterClass method.

 

  • Control Template – While writing a custom control we need to decide how its template will work. We should define the control by defining the idioms for the control liked the named parts. This tells what the control expects from its template. We can list parts we require by specifying the TemplatePart attribute. We need to declare the name of the part and the type it should be compatible with. Let’s see  this in action. Add a custom control to the project as shown in the image below.

 

WPF Custom Control

WPF Custom Control

Now let’s use the NamedParts idioms to specify what we want in the template.

 

WPF Custom Control

WPF Custom Control

The most important thing to do while working with templates is to override the OnApplyTemplate method as WPF will call this each time the control is given the template and this might happen multiple times. The first thing that we do here is check if the tenplate is not null and then we proceed to find the named part in this particular control. Then we cast it to the types of Shape. If the template named part is not null then we hook up a mouse down event handler and in this event handler we set the target fill property to green.

 

WPF Custom Control

WPF Custom Control

Now, Let’s use this custom control in our application

 

WPF Custom Control

WPF Custom Control

On MouseDown event the fill changes to green. So our handler works for the templates.

Themes

Most controls would want to have a default template. We generally do this by providing the compiled xaml resource by putting them in the themes folder. We should also provide generic.xaml  to provide the resources that might be needed when the resources specified by the user are not available. Also the assembly must declare the presence of these themes by using the Assembly Info attribute. This tells whether theme resources are present and whether generic resources are present. As we can see in the image below WPF added this information when we added the custom control.

 

WPF Themes

WPF Themes

WPF also added a Generic.xaml when we added the custom control and this contains a style for the custom control that we added.

 

WPF Themes

WPF Themes

Let’s add one more instance of the custom control without overriding the template and we will see something like below. The functionality of both of them is same but the appearance is different.

 

WPF Themes

WPF Themes

Designer Integration

We can integrate with design environments such as Visual Studio or Expression Blend. We can move all the general purpose design time code to a separate dll and we can follow the naming convention by adding .Design at the end of the class name. Or we can place the designer specific code in the dll with extensions .Expression.Design or .VisualStudio.Design in the end and if we install these dll so that they appear in the add reference panel then the designers weill be able to locate them.

We can put design time components in the toolbox for any design time environment. Visual Studio provide option to specify the Custom adorners or items in context menu or view or modify Object tree or property grid.

If we want use the design time dlls then the design time dll must include a implementation for IRegisterMetadata.

 

Any questions, comments or feedback are most welcome.

The code for this post can be found here.

 

Hey guys,

In this I am going to start talking about Windows Presentation Foundation or WPF in short. I hope you guys find this series interesting and informative.

So once you have decided to Learn WPF do not a step back or leave it in between because once learn the full power of WPF you would know how to create windows and web applications with awesome graphics easily.

What is WPF

At the very basic level WPF is just a framework which is used for building Windows application. Before WPF the windows applications majorly used couple of dlls (User32 and GDI32). These were the 32 bit versions of their 16 bit parents who were introduced in mid 1980s. Now if you have worked in Windows Forms you would know that the interface that you used to create an application were just a wrapper around these dlls.

Why to Use WPF

But WPF does not use GDI32 and barely uses USER 32. It’s not just a wrapper around these dlls. WPF was introduced as part of .NET 3.0 framework. It contains both managed and unmanaged code. It was designed from scratch so that .NET languages could be used to program in WPF. You would need to use .NET to use WPF as these are no public unmanaged API offered for this. This provides a lot of advantages as you don’t have to struggle with the issues you face using a wrapper around the unmanaged code. You need to be either on XP SP3, Vista, Windows 2003 or above to use WPF.

You might still be wondering as to what’s the thinking behind creating a new framework such as WPF when we already have a Windows Forms for creating a Windows application which is used by lot of people and huge numbers of people are skilled in it. The reason is Microsoft did not want to lag behind after all the thinking and market changes that have happened since the initial framework for creating windows application was launched and was really hard to keep the future versions compatible with it ancestors. As whenever an upgrade happens to a new version, people expect it to be really smooth. At the time when the initial Windows application development architecture was designed then the computer was not capable of so much processing power or graphical capabilities. Nowadays the computer hardware capabilities have progressed in leaps and bounds. So there was a need to design a framework that could utilize that capability. WPF provide the interface using which could design rich graphical user applications without having to deal with complexity of the directx or OpenGL code. Now the old dlls that were used in creating WPF application does not provide any way of utilizing the directx capability unless you are ready to program in directx or OpenGL.

WPF is also auto scalable by default which means that if you run you WPF application on machine with different DPIs you application will automatically scale its contents according to the DPI and resolution of the machine. You can simply see that in action by simply creating a WPF application and zooming into it. If you zoom into other applications or graphics in your system you see it getting pixelated but with WPF you will not see that.

As the times have changed, people’s expectations from the applications have changed. A decade ago people were okay with console application running on their computers but today they want a rich and cool user interface to work with. The games that we see now have reached that level and same can be achieved for windows application using WPF. You can make your complete application be blended into a single theme that you want, like your company logo colors, etc.

It was easy to make websites carry branding before using HTML as anyone without any programming experience can also use HTML to make a nice looking website which corresponds to your company. WPF also utilizes the power of Markup to give the designer the ability to do more and be part of the graphical interface easily. The use of markup makes the Windows apps move forward to the level of web apps styling easily.

Now in today’s time we do have the option to create a visually appealing application but the problem is to integrate all those component together that make that visually appealing application. We do have HTML for Web, Win32 with easy interface for Windows applications, DirectX or OpenGL for developing rich graphics application and Flash for designing rich vector graphics but all these have different capabilities and it’s really difficult to integrate all of them together. But WPF provides us with a single integrated solution for it. The capabilities that WPF provides are already available with the technologies I mentioned before but the advantage with WPF is that it provides all these capabilities at one place and integrated.

WPF Architecture

As you could see in the image below the basic architecture of WPF is designed with directx at its base above kernel.

 

WPF Architecture

WPF Architecture

WPF utilizes the 3D hardware your system to render 3D or 2D graphics on your system. On top of Directx level is the most basic component of WPF called as the Media Integration Layer or MIL. This is the component that takes the various types of media like the bitmaps, images, videos, etc and renders them all into a single directx surface. This MIL is unmanged code because it has to talk to directx and there need to be lot of calls need to be made to the com interface while dealing with directx and directx uses a lot com calls as they are cheap in its context but when you come to .Net code that is not the case. Using com from needs you to go through the interop layer and made thousands of call through the interop layer wil burn a lot of CPU cycle. So that’s the advantage to MIL, as to render a complex shape you make just one interop call to MIL and MIL then internally makes thousand and hundreds of com calls to DirectX to render that shape. Above the MIL we have two dlls for WPF. Presentation Core and Presentation framework. Presentation core is the public face of the MIL, it provides the .NET API that exposes he rendering services of the MIL. Above this presentation core we have the Presentation Framework layer that provides the high level services. Presentation layer provides the concept of Controls, layouts, data binding, animations, etc. As a WPF developer you would be spending most your time with Presentation framework. And you would be using the Presentation Core at the time graphics programming. The reason for separation of these layers is to make the rendering available without being dependent on WPF features.

What is XAML (Extensible Application Markup Language)

When you create a WPF application you would see two code files in your project. One is the regular .cs or .vb file which is your standard code file and the other one is you XAML file which is something new to WPF. Now a XAML file looks a lot like a XML file. Now if you would have created a WPF application in the past then you would have seen XAML. I would like clarify here that XAML is independent of WPF and WPF is independent of XAML. They are separable. XAML is nothing but a language to create .NET objects and this means we could what we do XAML in C# or VB code as well. It’s on you to decide what to use when. So if you see the image below you would find XAML and its corresponding C# code.

 

WPF XAML

WPF XAML

Now XAML uses the type converter infrastructure to map the string and integer values to map to the property values at the run time. And it also XAML in knows as to what does the content contain. The most simple and important thing about XAML is that it creates objects and sets properties. Also when you create a WPF application and open any of the XAML files you would see something like this at the top of it.

 

WPF XAML

WPF XAML

This is simply references to the namespaces so that you could use the components in that namespace. If you are referencing any namespaces in xaml then this is the place to add them. Microsoft took a long time in developing xaml and figuring out how xaml does what it actually does.

UI Tree in WPF

The XAML interface objects are built as trees of objects. As you would see in the code below,

 

UI Tree in WPF

UI Tree in WPF

Here we have root element which is a Window. This Window contains a single child which is Grid. The grid contains other children and it’s the Grid job to assign as to where these children are placed in the layout. So you see a tree root structure.

WPF provides two tree structures: The Logical Tree and The Visual Tree. The visual tree will be of use if you are concentrating on the presentation.  The Visual Tree is simply the super set of the logical tree. You can see below that all the children of the logical tree are present in the visual tree. So these two trees are the different views of the same set of the objects that make up the UI. The logical tree provides you with the detail to focus on the core structure of the User Interface and to ignore the details of how exactly it is presented.

 

Visual and Logical Tree in WPF

Visual and Logical Tree in WPF

 

Events and Commands in WPF

There are two ways for handling input in a WPF application: Events and Commands.

Events are very closely tied into the visual tree. Any Mouse or keyboard inputs originate from an element. The one with the focus – keyboard input and the one with the stylus – mouse inputs. As we have already seen that the visual tree was pretty complex for just a couple of elements, you could imagine the complexity if there are a lot of controls in your visual tree. It would become all the more complex if you add an event handler to every element of the visual tree to receive the inputs.

To save us from this complexity WPF has Event routing. Event routing allows the ancestor of the element to handle the event. Now there are two types of routing in WPF – Tunneling and Bubbling.

Tunneling starts from the root of the visual tree and goes through the tree and reaches the element to which the event is targeted. Generally Preview events are the ones that tunnels. Bubbling Event works in the opposite direction. It starts from the Element and goes up the parent to the root. Main events are the one that bubbles. The concept behind providing a preview is to give the parent element a chance to handle the originating event.

For example if you have a button in the Grid and you want to handle the Mouse down event. Now if you want Grid to handle the event before the Button does you need to use the Preview events (PreviewMouseDown) and if you want the button to handle the event first then you should use the main event (MouseDown).

Commands on the other hands help you do the same action through multiple inputs like a keyboard shortcut, stylus gesture, menu clicks, button clicks, etc. So that multiple inputs can use the same command if they want same job to be accomplished.

Controls

Controls in the previous versions like Windows forms correspond to behavior as well and presentation of an element, whereas in WPF controls are a bit different. Let’s take a Button for Example, a button has a click event which is an API feature related to the user interaction. It also supports the content Model for composition which is also an API feature. It supports Focus which is an interactivity feature. It can be associated with Command which is again an API feature. It also supports the Automation API which makes it accessible to screen reader, automation testing, etc. But there one thing that a WPF button cannot do which its activex, Win32 counterparts can.

A WPF button is a lookless control which means it has no intrinsic look and it does not know how to present itself. The look of a control in WPF is controlled a distinct entity known as Template. So button may look like a circle or a star but it will still support all the API and interaction features. Let see how this works in code.

Use the following code in a WPF application and you would be able set the template property for the button control.

 

Controls WPF

Controls WPF

 

You should notice a few things about the code above.

  • We have defined a ControlTemplate for the Button which changes the look and feel of the Button.
  • The Fill property of the Rectangle in the ControlTempalate is done using the TemplateBinding with Background. What this does is binds the Fill of the rectangle to the Background of the Button. So whatever background we set on the Button becomes the Fill of the rectangle.
  • You would also see Curly braces around the TemplateBinding which signifies that it a special property. This is considered to be Markup extension. Markup extension signifies that it would be decided at runtime as how this property will work. This syntax means that we need to create an instance of the TemplateBinding Class with Background as a string and a constructor parameter and WPF expects the whole thing inside the curly braces to derive from Markup extension base class. Now this Base class provides an abstract method named Provide Value. This method would be called at runtime to decide what value will the Fill property have a runtime. A custom markup extension can build depending on what we need.
  • You would also see the same thing as Rectangle Fill Property for TextBlock Text Property.

Lets change the code to look something like below:

 

Controls WPF

Controls WPF

You would now notice that the Content of the Button is now and Ellipse and to make that as the content of the button we need to need to use a ContentPresenter instead of a TextBlock because a TextBlock is a primitive control and it could only display text. So to display the any content we need to use the ContentPresenter and TemplateBind the Content property. So if we want any other content we could do that now.

Primitive Elements in WPF

As you have seen that the controls do not define their own look, so are you not wondering as to how do anything appear. Just as we saw above a button control derives its look from its template, and the controls derive their appearance from there templates so is there an infinite loop to look for the template?

That’s not the case. Only the controls have a template and most elements in WPF are not controls. Only the Controls that derive from the Controls Base class are supposed to have some kind of interactive behavior. Examples of controls are Button, TreeView, ListBox, TextBox, etc. Only the Controls derived from the Controls class have a template because it’s the Control class that introduces the template property.

Examples of Elements are Rectangle, Ellipse, Image, TextBlock etc. These do not derive from Controls and are more primitive and derived from FramworkElement (Base class for Controls as well). These elements do not have a template of their own and as they are more primitive and there presentation is specifically designed. Primitive elements are the one that provide an intrinsic appearance for them. These can be also considered to be lookful controls. Primitive elements do not have any intrinsic behavior of their own and you have to add the events and handler to get some interactive behavior from them.

You might note that a lot of elements that do not derive from the Control Class are placed in the namespace System.Windows.Control. This is confusing you should keep in mind that the Elements that derive from the Control Class are Controls.

Layout in WPF

The new and useful feature in WPF is the Layout primitive also known as Panels in have. The Panles are required at places where we need to position multiple childrens. The panels available in WPF are Grid (Advanced table/grid-based layout), Canvas (Fixed layout, supports anchoring), StackPanel (left to right and top to bottom layout), DockPanel (Docking layout) and WrapPanel (Flow-like formatting).

Flowed Text in WPF

WPF provides a flow layout for the text so that the text fits into whatever space is available. A Flow document has a HTML-like feature set and it has reader controls.

In a flow document we can integrate any mixture of text styles, user interface elements, HTML features (Lists, floating data, etc). WPF makes it much easier to render text in columns than HTML which is very useful because columns allow shorter line lengths which improves reading speed.

Data Binding in WPF

When you come across data binding you would think about databases or collections but in WPF databinding has much broader scope. Data Binding can be used at times when you want to present any data to the screen. WPF data binding either connects to objects or xml. WPF never assumes the presence of a database. Infact you never use data binding directly with database. You load the data from the database into your domain objects, datasets, etc and then data binding presents them on screen.

Data Binding brings up a very interesting concept in WP Known as DataTemplate. Similar to ControlTempalate which defines how a control should look like, DataTemplate defines how the data should look like. So you define the template for a particular class of application and the template can be used to present the data on the screen.

Its because of the power of Data Template that WPF does not contain a DataGrid as you could define how the data should be presented on screen.

Deployment

There are multiple ways in WPF to deploy the application to the user machine:

  • Build a MSI installer
  • Click Once deployment but is supported only in full trust environment.
  • XBAP – XAML Browser application. This is like the Click once but imparts the experience like the java applet style. This does not require full trust as it runs in browser.
  • .NET 3.5 SP1 deployment options
    • Client only framework – option to deploy only a part of the framework. Can be deployed in following ways:
      • Setup bootstrapper – this installs the framework before going to the normal windows setup
      • Deploy via Click Once

The code for this post can be downloaded here.

Any questions, Comments and feedback are most welcome.

 

Extending your Silverlight 4 Application with Controls

We could not only use and extend the controls present in the visual studio toolbox for Silverlight but also there are multiple providers offering additional controls for Silverlight framework.

Extending XAML

XAML stands for eXtensible Application Markup Language and hence it’s possible to add import external elements into a document without breaking rules.

Mapping a Prefix to CLR Namespace

Now we can define a set XML namespace (xmlns) in XML and can map a unique identifier to a prefix so that the XML parser can use additional rules while loading the document.

For Example

Lets say we want to add double value in the document resources. Now as you would know that XAML is by default configured for User Interface elements, the default XML namespaces will not map to Double types so we have to add the line of code shown in Bold in your XAML other than the normal code.

 

<UserControl x:Class="DoubleInResources.MainPage"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

xmlns:sys="clr-namespace:System;assembly=mscorlib"

mc:Ignorable="d"

d:DesignHeight="300" d:DesignWidth="400">

<UserControl.Resources>

<sys:Double x:Key="ButtonsWidth">200</sys:Double>

</UserControl.Resources>

<Grid x:Name="LayoutRoot" Background="White">

<Button Width="{StaticResource ButtonsWidth}" Height="{StaticResource ButtonsWidth}" Content="Click Me!!" />

</Grid>

</UserControl>

 

So we are including the mscorlib namespace which contains the Double type definition and then referencing the same in UserControl.Resources and then we have referenced the same as a static resource.

Note

When we are working with XAML we encounter two types of namespaces

CLR Namespaces – Used in .NET code to group the classes logically.

XML Namespaces – Used to extend XML document with additional declarations.

Prefix is not always needed

Silverlight elements are defined into two namespaces. The first one is a Unique Resource Identifier (URI) mapped to the default xmlns (http://schemas.microsoft.com/winfx/2006/xaml/presentation).

 

In fact, multiple CLR namespaces (such as System.Windows.Controls, System.Windows.Shapes, and so on) are mapped to this URI. This allows us to use all the types within these namespaces without having to use a prefix. For example, we write <Button Click=”Button_Click” /> and not <anyPrefix:Button Click=”Button_Click” />. Note that this URI is not a website’s address, and entering it into a web browser will not lead you anywhere. It is just a Unique Resource Identifier, a unique name.

 

The other namespace used by Silverlight by default is http://schemas.microsoft.com/winfx/2006/xaml, another URI, which is mapped to the x prefix. Inside this namespace are defined additional properties that can be applied to any element.

 

How to add a namespace to any element

You can a namespace mapping to a control as well as shown below:

<Button xmlns:controls=”clr-namespace:MyApplication.Controls”>

<controls:MyControl />

</Button>

 

How to define your own CLR and Mapping CLR Namespaces

We can map our own URI to a group of namespaces and this is useful because we can consolidate multiple CLR namespaces into one single URI and also this would hide the CLR namespaces that our code is using. And later when we decide to move some classes to different CLR namespaces we don’t need to change the XAML code. This is also very useful in creating data objects and it also makes data binding easier.

For Example:

Add the following code to the AssemblyInfo.cs

 

[assembly: XmlnsDefinition("http://www.mycompany.com", "DoubleInResources")]

[assembly: XmlnsDefinition("http://www.mycompany.com", "DoubleInResources.Controls")]

[assembly: XmlnsDefinition("http://www.mycompany.com", "DoubleInResources.DataAccess")]

 

And then after building the solution we can reference it as shown below:

What is a Control?

I know you would say that you know what it is but lets start with a formal definition of Control. A Control is an element of software, encapsulating some functionality related to user interface. Now in Silverlight there are two kinds of controls User Control and Custom Control.

User Controls

A user control is a logical group of other controls. It is typically used to separate a user interface in smaller parts that are easier to code and design. In fact, in Silverlight, all the pages of an application are user controls.

The App class (defined in App.xaml and App.xaml.cs) is the main point of entry for the Silverlight application. This is also where the MainPage control is created and assigned.

The Application_Startup Event Handler in App.xaml.cs is as follows:

 

 

 

If you rename the MainPage control to a different name, you must also change the name in the RootVisual assignment, or else your application will not compile anymore.

 

Custom Controls

The custom controls are made of code only as against XAML (Front End) and a code behind file. All controls build in Silverlight are lookless. The custom control file defines only the controls functionality i.e. Properties and methods and its behavior is defined by its states and parts.

For the controls to be visible, a XAML front end must be defined, though. An invisible control is not very usable! One control can have multiple appearances, defined in as many control templates. We talk out a separation of concerns: The control’s code defines its functionality; the control’s template defines its appearance. Typically, a developer implements the control, whereas a designer styles and templates it.

 

Design a Custom Control

 

Let’s take the example of a Custom with the following functionality:

 

  • The user defines a threshold and a value, both of type Double.
  • If the value is higher than the threshold, the control is in High state.
  • If the value is lower than the threshold, the control is in Low state.
  • If the value is equal to the threshold, the control is in Equal state.
  • Both the threshold and the value can change dynamically, be data bound, animated, and so forth.
  • The user can click one part of the control to increment the value by one unit, and another part to decrement by one unit.
  • The control can be disabled, in which case clicking does not change the value.

 

Now as you see we have the functionality of the custom control but not how the control will look so the developer can start working the designers can do the designing part simultaneously.

 

Let’s get started:

 

  1. In Visual Studio, select File, New, Project from the menu.
  2. In the Add New Project dialog, in the Silverlight category, select Silverlight Class Library.
  3. Enter the name CustomControlsLibrary and click OK. Make sure that you select Silverlight 4 in the next dialog. This creates an assembly, a library that can be referenced in multiple applications but cannot be run on its own.
  4. Delete the file Class1.cs in the Solution Explorer (because will not use it).
  5. Right-click the CustomControlsLibrary project in the Solution Explorer, and select Add, New Item from the context menu.
  6. In the Add New Item dialog, select the Silverlight, and then select a Silverlight Templated Control.
  7. Enter the name ThresholdControl.cs and click Add.

Defining the Parts and States

These steps create a C# code file, a folder named Themes, and a XAML file named

Generic.xaml. We will investigate this last file later; for now let’s declare the parts and

states for this control:

  1. Open the file ThresholdControl.cs.
  2. According to the requirements, the control has two state groups. We will call these the Common states (Normal, Disabled) and the Threshold states (High, Equal, Low). Note that the states within a state group are mutually exclusive; that is, the control cannot be simultaneously in Normal and in Disabled state. However, it can be Normal and High, or Normal and Low, and so forth. Defining the states and states groups is done with the TemplateVisualState attribute on the class.
  3. The requirements also state that the control has two parts with a special meaning: Clicking them increments or decrements the value. Here too, we use an attribute to define the parts on the class: the TemplatePart attribute.

 

The ThresholdControl.cs should look like this

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace CustomControlsLibrary
{
    [TemplatePart(Name = "IncrementPart", Type = typeof(UIElement))]
    [TemplatePart(Name = "DecrementPart", Type = typeof(UIElement))]
    [TemplateVisualState(GroupName = "Common", Name = "Normal")]
    [TemplateVisualState(GroupName = "Common", Name = "Disabled")]
    [TemplateVisualState(GroupName = "Threshold", Name = "High")]
    [TemplateVisualState(GroupName = "Threshold", Name = "Equal")]
    [TemplateVisualState(GroupName = "Threshold", Name = "Low")]
    public class ThresholdControl : Control
    {
        public ThresholdControl()
        {
            this.DefaultStyleKey = typeof(ThresholdControl);
        }

        public double Value
        {
            get
            {
                return (double)GetValue(ValueProperty);
            }
            set
            {
                SetValue(ValueProperty, value);
            }
        }

    public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(double), typeof(ThresholdControl), new PropertyMetadata(0.0, OnValueChanged));

    public double Threshold
    {
        get
        {
            return (double)GetValue(ThresholdProperty);
        }
        set
        {
        SetValue(ThresholdProperty, value);
        }
    }

    public static readonly DependencyProperty ThresholdProperty = DependencyProperty.Register("Threshold", typeof(double), typeof(ThresholdControl), new PropertyMetadata(0.0, OnValueChanged));

    private static void OnValueChanged(object s, DependencyPropertyChangedEventArgs e)
    {
        var sender = s as ThresholdControl;
        if (sender != null)
        {
            sender.GoToThresholdState(true);
        }
    }

    private void GoToThresholdState(bool useTransitions)
    {
        if (Value > Threshold)
        {
             VisualStateManager.GoToState(this, "High", useTransitions);
        }
        else
        {
            if (Value < Threshold)
            {
                 VisualStateManager.GoToState(this, "Low", useTransitions);
            }
            else
            {
                 VisualStateManager.GoToState(this, "Equal", useTransitions);
            }
       }
    }
    
    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        var incrementPart = GetTemplateChild("IncrementPart") as UIElement;
        if (incrementPart != null)
        {
            incrementPart.MouseLeftButtonDown += new MouseButtonEventHandler(IncremementPartMouseLeftButtonDown);
        }
        var decrementPart = GetTemplateChild("DecrementPart") as UIElement;
        if (decrementPart != null)
        {
            incrementPart.MouseLeftButtonDown += new MouseButtonEventHandler(DecremementPartMouseLeftButtonDown);
        }
        GoToThresholdState(false);
    }

    void IncremementPartMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        Value++;
    }
    void DecremementPartMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        Value--;
    }
    }
}

 

And the Generic.xaml should look like this:

<ResourceDictionary

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:local="clr-namespace:CustomControlsLibrary">

<Style TargetType="local:ThresholdControl">

<Setter Property="Template">

<Setter.Value>

<ControlTemplate TargetType="local:ThresholdControl">

<Border Background="{TemplateBinding Background}"

BorderBrush="{TemplateBinding BorderBrush}"

BorderThickness="{TemplateBinding BorderThickness}">

<VisualStateManager.VisualStateGroups>

<VisualStateGroup x:Name="Threshold">

<VisualState x:Name="High">

<Storyboard>

<DoubleAnimationUsingKeyFrames

Storyboard.TargetProperty="(UIElement.Opacity)"

Storyboard.TargetName="EqualTextBlock">

<EasingDoubleKeyFrame

KeyTime="0" Value="0" />

</DoubleAnimationUsingKeyFrames>

<DoubleAnimationUsingKeyFrames

Storyboard.TargetProperty="(UIElement.Opacity)"

Storyboard.TargetName="LowTextBlock">

<EasingDoubleKeyFrame

KeyTime="0" Value="0" />

</DoubleAnimationUsingKeyFrames>

</Storyboard>

</VisualState>

<!--...-->

</VisualStateGroup>

</VisualStateManager.VisualStateGroups>

<Grid>

<Grid.ColumnDefinitions>

<ColumnDefinition Width="30" />

<ColumnDefinition Width="*" />

<ColumnDefinition Width="30" />

</Grid.ColumnDefinitions>

<Border Background="Blue" x:Name="DecrementPart"

Cursor="Hand">

<TextBlock Text="-" />

</Border>

<StackPanel Grid.Column="1"

Orientation="Vertical"

Margin="10">

<TextBlock Text="{Binding

RelativeSource={RelativeSource TemplatedParent},Path=Value}" />

<TextBlock x:Name="HighTextBlock"

Text="&gt;" />

<TextBlock x:Name="EqualTextBlock"

Text="==" />

<TextBlock x:Name="LowTextBlock"

Text="&lt;" />

<TextBlock Text="{Binding

RelativeSource={RelativeSource TemplatedParent},Path=Threshold}" />

</StackPanel>

<Border Background="Red"

x:Name="IncrementPart"

Grid.Column="2"

Cursor="Hand">

<TextBlock Text="+" />

</Border>

</Grid>

</Border>

</ControlTemplate>

</Setter.Value>

</Setter>

</Style>

</ResourceDictionary>

 

 

You can find the complete Source Code at http://min.us/mKwMNIhKq