WPF Customization Continuum

When Microsoft designed WPF they also thought about customization continuum which was not present in Windows Forms. To some extent it was present in Windows Forms but it required writing code and take control of the rendering of the control  or else we had to write a custom control altogether. MS referred to this problem as the owner draw cliff.

 

WPF Controls are called as lookless controls and the templates can be used to change the appearance of a button to circle with one line of xaml.So a WPF controls has properties, events, commands, etc for it but it does not know how to display itself. So we display a button in multiple formats using just a line of xaml and define the control’s Template.

 

Control Template

A Control Template describes what goes into the visual tree to represent a template. As you can see in the code below that the button template contains nothing but ellipse. Also the buttin still has the functionality of a button like the events but it looks like an ellipse.

 

WPF ControlTemplate

WPF ControlTemplate

Template Binding

The most important thing that a template do is connect the properties of a template to the properties of a control. As we can see in the code below we have used TemplateBinding. Now whatever background property I set on the button will be passed to ellipse for the background.

 

WPF TemplateBinding

WPF TemplateBinding

But if you change this Template Binding to ordinary Data Binding then the background stops working. The reason is that this binding does not have a DataSource so it tries to use the data context of its target element. But the Ellipse has no DataContext. So we would think that it will get the DataContext from the ControlTemplate which in turn will get its DataContext from its Target Element which in this case is the Button. But Button does not have a data context and nor does the page. And hence the DataContext is null and that is why nothing is happening.

 

WPF TemplateBinding

WPF TemplateBinding

 

We can point the DataContext or source to a control. We can also use a property called RelativeSource. RelativeSource looks up the binding by looking up the visual tree. We can do it in two ways:

  • We can specify the type of control to look for
  • Or we can specify the control

In this case we have specified the RelativeSOurce to be the TemplatedParent. The TemplatedParent means whichever template this object was instantiated for. This works but ots crumbersome to use, so we have the simpler TemplateBinding itself.

 

WPF TemplateBinding

WPF TemplateBinding

Another reason for the existence of TemplateBinding is that even though DataBinding is powerful it is heavy weight because of Value conversion, two way binding and validation.

Triggers

Like Data Templates Control Templates can have Triggers. They support Event Triggers and Data Triggers as well as Property Trigger. The difference between a Data Trigger and a Property Trigger is the same as Data Binding and Property Binding. While Data Binding monitors the property of the Data Source, a Property Trigger monitors the changes in the Control’s Template property change.

 

WPF Trigger

WPF Trigger

Generally the way these triggers work is that there is a named element inside the Controls Template and then the triggers specify the name of that element as the target. It helps us have effects on the parts of the controls that do not directly connect to the public properties of the control.

 

WPF Trigger

WPF Trigger

Contract between Controls and Templates

Controls depend on templates to provide certain visual features and templates depend on controls to provide behaviors. So there is contract between the controls and its templates and this contract varies in complexity. For a Button the contract is very simple. The two things that a Button asks its template to provide is

  • Bubbling of the mouse events. This is mandatory as if this is not provided then the button will not able to raise the mouse events and hence it will not function as a button. But this implemented by default so nothing needs to be done there.
  • Provide a place for content place holder. This one is optional as all buttons might not need content.

A complex contract example can be a scrollbar. As a Scrollbar contains a dragable thumb area whose size is proportional to the area to be scrolled. Also its movements should be constrained within the bounds of the clickable arrow buttons. So scrollbar does is define a control called Track in Windows.Controls.Primitives namespace whose only job is to define the dragable region of the scrollbar and sliders. The Track imposes structure and has 3 properties to hold the 3 parts of the track.

  • The Thumb – Mandatory
  • Up and Down Repeat Buttons – Optional. It is a control in the primitive namespace and has an additional functionality of repeating itself when it is kept pressed down.

The Specialized control named Thumb is also part of the primitive namespace. It is a Content control that provides events to control the drag operations. WPF uses it not only in the scrolllbars but also the resize control at the bottom right of the resizable window. This can be used by developers if a dragable control is needed in the user interface.

The scrollbar needs the lineup and linedown commands to be implemented but it does not care if it’s a hyperlink or a repeat button. It will just move up or move down by one line.

Also the empty region of the scrollbar which might seem like the track area is the place where the PageUp and PageDown commands are implemented for buttons.

 

Contract kinds

The Contract kinds can be of types below.

  • Named Parts – The control mearly requires the template to contain certain names. A ProgressBar is an example of a Named Parts Control. We can see the customized template of the ProgressBar below. The two of the controls in the progress bar template have named and these are names that the control will look for. The documentation tells us to define the PART_Track which tells the control the area to sweep. And the PART_Indicator that the control will resize when the value property changes and adjust the indicators width to show the progress. If we do not provide these named parts then the progress bar will not complain. The nature of the progress bar is that if you want it to do the resizing then you provide the named parts.

 

WPF Named Parts

WPF Named Parts

  • Common Idioms – The Standard ways in which the controls work
    • ContentControl – This is one of the common idioms for the controls. This is used by a button. The template is required to provide the ContentPresenter to provide the content.

 

WPF ContentControl

WPF ContentControl

  • HeaderdContentControl – This is like the ContentControl. It has 2 ContentControls. One defines the Content and one defining the Content for the header of the control.
  • ItemsControl – Items control are a bit complex and it is a bit unusual that they provide template for each individual control. A problem with WPF template model model is that it is an all or none proposition. If we want to make a template which is slightly different from the default template we need to replace the whole template. But ItemControl provide more fine grain templating by providing three important properties.
    • ItemsPanel
      • ItemsPanelTemplate – It is the 3rd type of template provided by WPF. Let’s see it in action. Add the following code to the Window.

 

WPF ItemsPanelTemplate

WPF ItemsPanelTemplate

However while defining the ItemsPanelTemplate we have turned off the virtualizing feature and this will degrade the performance of the ListBox when it has lot of items. But if we use VirtualizingStackPanel we will still be able to enjoy speedy performance. However this VirtualizingStackPanel is the only virtualization aware control. We can also write our own Virtualizing panel.

  • ItemsTemplate
    • DataTemplate – This helps us customize the appearance of the indivisual elements without having to customize the whole control.
    • Template (Whole Control)
      • ControlTemplate– This will replace the appearance of the whole control. Below is the ListBox using ControlTemplate. It requires only two things.
        • If we want scrolling then we need to provide a scrollviewer. The control template will look for this as it will need the scrollviewer to collaborate with the virtualization. If it doesn’t find then it will turn off the scrolling.
        • We need to provide the placeholder for the item. We need to use an Itemspresenter in the template. We can also place a VirtualizingStackPanel and set the IsItemsHost property to true. By doing this the ItemsPanel Template is completely ignored and Panel in the ControlTemplate is used. But if wants the flexibility of using different layouts then we can use the ItemsPresenter in the ItemsTemplate.
  • HeaderedItemsControls – Combines ItemsControl Functionality with ContentControl features. We can use templates with the mixture of both styles.As you can see in the code below we have a StsckPanel whose IsItemsHost property is set to true. And then we have the ContentProvider that will provide the TreeViewItem header property. Also TreeView ItemsTemplates need to provide a toggle button to provide the functionality of a toggle button to expand and collapse the node. We have used a CheckBox here and we have used DataBinding inside it as opposed to ItemsBinding because ItemsBinding supports only one way binding.

 

  • Control specific Custom Contracts

Templates are Factories

Template is a slightly different object than the user interface elements normally deal with. We place the same button at two different places in the user interface then it will complain as one UI element can have only one parent. But we can use the same template multiple times without any error. The reson is that Templates are factories and everytime they are used WPF creates a new copy. This applies to both DataTemplate as well as ControlTemplate. The base class for templates i.e. FrameworkTemplate provides a method to generate a copy of the template named LoadContent. This means the mapping of XAML and code is not quite as straight forward as other markups. The XAML enters a different mode when working with a template. So instead of generating an Ellipse in the example shown below, it actually generates a Factory to generate an ellipse with the specified properties.

 

So it creates a ControlTemplate Object and its content becomes a Tree of FrameworkElmentFactory. Each element in the template becomes a new factory object and this factory structure corresponds to the xaml tree structure. And this tree of factories becomes the template property for the visual tree.

 

Logical and Visual Tree

So we have now seen enough to know how the control expands from a single logical nod to a set of nodes in the visual logical tree. When the Visual Tree is loaded the Control reads its own Template property and then calls LoadContent on that causing the FrameworkElement factory tree to generate a new instance on behalf of the button. The control then attaches this to the visual tree by using the helper class named Visual Tree Helper and that’s how a control gets to appear.

Any questions, Comments or feedback are most welcome.

The Code for this post can be found here.

 

DependencyObject

DependencyObject provides WPF property system. The WPF system needs the needs the properties to have a richer set of services like change notification is required for triggers and data binding. So apart from Change Notifications we also need Default Values, Type Coercion, Data Binding, Attached Properties, Validation, Inheritance down the Visual Tree and Styling to be available for the properties. It’s not feasible to implement all these features to a property every time we use it, so it’s really helpful to have these features already present in the properties. DependencyObject is the base type of most of the types we work in WPF and hence they already have all these features of the DependencyObject.

DependencyProperty

To use a dependency Property we need to do the following things.

  • Derive from DependencyObject
  • Register the DependencyProperty by passing the name of the property, the type of the property, the type that owns the property and the metadata for the property.
  • As per convention make it public static and readonly.
  • The assessors for the property become one liner by getting and setting the dependency property.

 

The dependency object that gets returned by register is used to identify the property.

The metadata can define the default value of the property, callbacks from the receiving property change notification, performing value Coercion.

The Change Notification handler is passed as a part of the metadata. WPF will call this handler anytime the property value changes. Only the property changed directly will go through the set assessor. The changes originating from styles, data binding, triggers, animation will not go through the set assessor. So the callback is useful these changes. So we can write the static callback function as it goes through the static property.

 

Attached Properties

These are not very different from Dependency property. The problem is that C# does not provide any built in syntax for attached properties so we have use RegisterAttached to register an attached property and define the get and set access for the property.

 

Inheritance

Inherited properties are the ones whose value cascades down the visual tree and to all decendents of the target window. So when we apply a property like FontSytle it cascades down the child elements as well. To enable this we need to pass the inherit flag while constructing the metadata. We should avoid callback function along with the inherited properties because it will be called for each and every child element of the visual tree.

 

UIElement and ContentElement

The Visual class derives from DependencyObject and it’s the base class for the everything in the Visual Tree. We cannot derive our class from Visual though. It has functionality which might change in future version and hence is not made public. We can derive from UIElement. Practically UIELement is the base class for all visual elements in the visual tree.

Another class called the ContentElement is the base class for the text based elements like the Paragraph, span, italic, etc.

 

Core and Framework

Visual, UIElement and ContentElement are part of Presentation Core. Framework Element is the baseclass of User Interface elements whereas as ContentElements is the base class for text elements. As you would know WPF is splitted into core rendering services and high level framework services that provide binding, styling and so on. So Framework element is the base class of UI elements and FrameworkContentElement is the base class of text elements. You should know that DependencyObject is neither a FrameworkElement nor FrameworkContentElement type. It lives in WindowsBase dll. This contain WPF types which are not user interface elements.

 

Freezeable & Animatable

The Freezable class also derives from DependencyObject and the base class for brushes, pens, animations, 3D models, etc. In other words it’s the base class that defines the types that define the user interface elements rather than having the behavior themselves. One feature of Freezable elements is that they can be reused and if the value of the element is changed it will be updated at all the places. But this comes with a cost as WPF will have to remember at all the places where this element is used. But if we never want to change it then we can freeze the element. And once frozen the element will throw an exception changing and hence we have saved the cost of remembering the where all the element is used. Freezing is also useful in threading. As we know that DependencyObject supports threading but we can change the element on the thread on which it was created. But freezing helps us created an element on the worker thread and pass it on the UI thread when we are done. Freezing is really effective for large 3D complex models.

Animatable derives from Freezable. All the animation types derive from freezable except the animation object. Most of the freezable types are the things we might want to animate like a Brush’s color or a geometry’s shape. So these things are are valid targets for animation. But we also want to make animation themselves the target of animation. And 2nd order animation is not supported by WPF. So animation are one type of freezable that do not get to be a target of an animation.

 

Any questions. comments & feedback are most welcome.

 

Data Binding is one of the most important services offered by WPF. Data Binding just means connecting the user interface to the information to be displayed. The data source can be properties data from the database, xml or other element property which includes the graphical elements as well.

Binding Targets

Data Binding has a Target and the Target has to be an element in the User Interface.  The syntax below can be used for the Data Binding.

 

WPF Binding Target

WPF Binding Target

Binding is the class that derives from the markup extension base class. And the various properties of the Binding object can be set. This binding object will be incharge of the Text property value of the object. The object that owns this Text property can be FrameworkElement. We can also bind to framework content elements. WPF also allows us to bind with certain types that are not framework elements but can be associated with them like the Brush object. So as long as Brush is a property of the Framework Element we can use it in binding. Binding is a framework service and Binding also takes into account context of the Visual Tree. The Target property has to be a dependency property. A dependency property is a property which is managed by the WPF property system and almost all properties of framework elements are dependency properties.

Binding Expressions

As far as the source of the binding is concerned any .NET object can be used as a source. We also need to specify what part of the source we are talking about. So the binding markup syntax lets us set that. So using the Path property of the Binding helps us specify which property of the source object is to be used as a binding and if want to bind to the entire object rather than a property of the object then we do not need to specify the Property. If we are binding with an XML then we need to bind to the XPath property to specify the element to bind to in the XML. Another important property in Binding is Mode which determines which way the binding will behave with the source.

 

The binding system of WPF defines the appropriate default modes for the various WPF elements. For Example it will default the mode to two way for a textbox and one way for textbock.

Bindings in Code

In xaml we use markup extension to define our bindings. In code we can set the binding directly by calling the SetBinding method of the FrameworkElement. We have passed the path as a constructor parameter.

 

WPF Binding in Code

WPF Binding in Code

Another way of setting the binding is by using the BindingOperations helper class. This is useful when we are not aware of the target type at the compile time.

Explicit Data Source for Binding

For a binding to work properly we need to define its source. In the example below we have explicitly specified the Source for the Binding in xaml. So we have specified the source as current thread and the path as CurrentCulture.

WPF Explicit Data Source Binding

WPF Explicit Data Source Binding

 

But you should know that this is not how usually the Binding is done in WPF.

Explicit Data Source as Resource

This is somehow close to the way we usually do the data binding. We have a source object placed in the Resources section and multiple objects are using this source object. The Resources object is a dictionary in which we can put useful objects. And then we have bound this source objects to multiple textblocks. One of them does not specify a path so the textblock is bound to the entire source object and the source being a string it works out fine. The second textblock specifies the path as the length property

 

WPF Explicit Data Source Resource

WPF Explicit Data Source Resource

Data Contexts

Let’s see how we usually do data binding in WPF. With the use of data context we can hook up multiple controls to share the same source for the data bindings. We have set the data context property of the Grid. If the Source property is not set in the Data Binding then the Control looks for the Data Context. But there is no Data Context for the TextBlocks but just for the Grid. Data Context is an inherited property and the way It works is it flows down to the descendants so the textblocks inherit the data context from the grid. And this DataContext becomes the implicit source of these bindings and the bindings just specify the path.

 

WPF Data Context

WPF Data Context

You would notice that I have not specified the properties (Platform, Version and ServicePack) as path. This is valid as we saw in the previous section we used a constructor to specify the path same is the case here when xaml interprets these properties as the constructor arguments.

Let’s build a WPF App with Custom Class and Data Binding. Let’s create a class named Person and it will have two properties: Name and Age. Add the following code to the Person class. This class will act as a data source for us.

 

WPF Data Context

WPF Data Context

Now let’s design the User Interface for displaying the data. Add the following code the xaml. You will see that we have set the binding on the text property of the nameText and ageText to the Name and Age properties of the person class.

 

WPF Data Context

WPF Data Context

When we run the application we will see that the textboxes have picked the name and age properties.

 

WPF Data Context

WPF Data Context

As you know by default TextBox have the Binding Mode set as TwoWay. Let’s add a button to test this.

 

WPF Data Context

WPF Data Context

When we run this we will find that that when we click on show button after making the changes we will see that the value of the property is updated. But if we use the shortcut key Alt+S, we will see that the value of the property is not updated. The reason is that by default WPF updates the target when the focus is lost from the control. When we click the Show button by mouse the focus is changed from the textbox but when we use the Alt+S keyboard shortcut the focus is not changed and hence the target is not updated. To fix this we need to set the binding property named UpdateSourceTrigger to PropertyChanged on the textbox. So whenever the property is changed the source is updated.

 

WPF Data Context

WPF Data Context

When we run the application now and use the Alt+S we will see that the property is updated straight away. Now let’s see what happens when the source is updated. Let’s add another button to the view and a handler for it.

 

WPF Data Context

WPF Data Context

When we run this and click on Age + 1 button we will see that the textbox age value is not updated but when we click on show we see that the property is updated. The reason is that the data binding is not polling the property regularly as we have not told it to do so. So let’s the WPF know to poll the property. One way to do is to call the UpdateTarget on the Age + 1 button click.

 

WPF Data Context

WPF Data Context

Now when we run the application we will see that the display is also updated along with the property but this very crude way of updating the display. So let’s remove this UpdateTarget call from our code and let’s go to Person class and implement the INotifyPropertyChanged interface. This interface consists of a single event that gets raised anytime a property is changed. Also we modify the set accessor to call the change notification.

 

WPF Data Context

WPF Data Context

Now when we run the application everything works out to be fine.

Data Templates

It is very common for an application to show same kind of data over and over or show the same data at multiple places. WPF provides Data Templates for this purpose. So if we specify the Data Template for a class then that class can use it for displaying the data. The data template could work by just specifying it in the xaml along with the binding expressions.  Let’s copy the xaml from the previous sample and add it inside the data template.

 

WPF Data Context

WPF Data Context

And let’s add the following code to the code behind.

 

WPF Data Context

WPF Data Context

This way we have used data template for the task which were doing before using data template. To see the usefulness of the Data Template we need to add the following code to the code behind.

 

WPF Data Context

WPF Data Context

Now modify the xaml to make use of this data source which is a List of Person.

 

WPF Data Context

WPF Data Context

Here we have used the Person class as our item template but we can also set our item template property inline in xaml or when we specify our data template on the resources we might give it a key and then we can refer to that by using the key in the resource markup extension.

Data Triggers

There would be a requirement at times when you want to change some property of the control based on the change in value or data. So that is when Data Triggers come into picture as they will help us distinguish the data templates. Let’s see a Data Trigger in action. As we can see in the image below we have added a data trigger in Data Template so that whenever the value of the Age property becomes 21 the background of the label will change to Red.

 

WPF Triggers

WPF Triggers

Triggers are pretty basic and they can only check constant value. We cannot do any complex checks with triggers. But we can take care of that via ValueConverters.

We can also use data triggers to trigger animation. Just add the code below to the xaml file.

 

WPF Triggers

WPF Triggers

We can also use EventTriggers or MultiTriggers in DataTemplates as well.

Binding To Collections

As we can see in the image below we have binded the ListBox to a Collection of SystemFontFamilies. You will also notice that we have not set the binding here just mentioned the static resource. The ItemsControl does not mind this until its getting a collection in return to bind to. We have set the Data Template inline. Here we have bound the TextBlock to a Non Text property which is the Font Family object itself. All ItemsControl (ListBox, ComboBox, ListView, TabControl, TreeView, Menu) support this kind of binding. We should be cautious not to add any items to its children or to its items property if we have used the ItemsControl property. An ItemsControl must be either used in the DataBound mode or the normal mode. Otherwise addig items to the ItemsSource while it already has children will result into exception.

 

WPF Collection Binding

WPF Collection Binding

Master Details of Selected Item

We might often want to showcase additional detail of the item selected. Let’s take help of an example to showcase this. Add the code shown below to the xaml. The ListBox part of the code is quite similar to the previous section except one additional property IsSynchronizedWithCurrentItem. This is because the data binding susyem will keep track of currently selected item data source and these controls are not required to sync with that so we want them to be in sync. We have also used the textboxes to display these additional details and you would see that we have bound the text property of the textboxes to a single property and this property is not present in the collection which is set to data context. So the data binding system checks if this property is present in the currently selected item and as it does it displays that value.

WPF Additional Info Binding

WPF Additional Info Binding

So we are relying on the data binding to fail in 1st attempt in order or the data binding to work. So we can fix that by adding a / to the binding and this will mean we want to bind with the currently selected item.

 

WPF Additional Info Binding

WPF Additional Info Binding

You might also notice that we have used [en-us] in the FamilyNames textblock this is because the Font Name sis a dictionary and it has different values in different culture and we are passing the locale to look entry in the dictionary. We can also dig down into sub properties by using the . syntax.

Hierarchical Binding

Sometimes we might want to bind to a data source which has child items and we would want to them to display as well so we can use Hierarchical Binding in that case. Let’s see this in action. So we have created a XmlDataProvider in Grid.Resources and then referenced it into the Hierarchical Data Template of the treeview.  And insideproperty of that we have a textblock whose text is set to xpath as title and the hierarchical data template’s itemssource property is set to xpath item. The item expression will select all the child elements called items. The same technique works for menus as well. This xml data provider can be inline or external.

 

WPF Hierarchical Binding

WPF Hierarchical Binding

The Data binding system does not make a big distinction between the xml data binding and xml data binding. We can actually mix them. Let’s see that in action. So change the XPath to Path in the TextBlock and then look at the NodeType or InnerXML or Value. So for data binding these are just objects. We can also use ordinary property style binding and xml data binding together.

Since the XMlDataProvider just uses the XML.Dome classes from Syem.XML namespace we can use the following code in the code behind to load the xml directly into the data context.

 

XML Namespaces

This is where binding with XML gets complicated. If we are not using any namespaces the xml data then the xpath would just work with the document classes. So as seen below the expression works fine with a document with no namespace but if the same expression is run with the same document but namespace then the query will return nothing.

 

We can use namespace aware syntax to do the proper data binding. We cannot specify the namespace of xml as we use to refer types in xaml. Instead we will have to use the XmlDataProvider.XmlNamespaceManager and then use the helper class XmlNamespaceMappingCollection. Then we add the Prefix as the xml namespace reference.

 

WPF XML Namespaces

WPF XML Namespaces

CollectionView

Every time we bind a ItemsControl to an XML node or an object WPF creates a collection view. This is object that manages that collection for the data binding purposes. Actually it’s the CollectionView that knows the currently selected item for that CollectionView. The CollectionView sits between the Source and the View and provides other services like data sorting, callback functions to fill the view and data grouping.

Let’s see the grouping service of the collection view at work. Add the following code your xaml file. We have to tell the collection view about our grouping requirements. Now you should remember that the collection view is always created at runtime so we cannot access it in xaml directly. So instead we have to use a collectionViewSource. This is the description in xaml that tells WPF to how to configure the CollectionView. So we have binded the collection view to the data source and grouped it from the GroupName attribute. We can have more than one CollectionViewSource for any collection. Also the controls will have to specify this CollectionView as their View Source to override the default view to that specified by the CollectionView.So we have set the ItemsSource of the MenuItem to our collection ViewSource. By default all ItemsControl have the abailty to put headers in groups and we can do this by specifying a group style which uses a data template. So we have use dthe grouping information coming from the CollectionView Source.

 

WPF Collection View

WPF Collection View

INotifyCollectionChanged

This is the interface similar to INotifypropertyChanged this interface reflects the collection level changes and its already implemented in the ObservableCollection. So this will works with Lists so when the items change on the complete list this will send the notification.  If we use a list and add items to it then the same will not reflect on the user interface even we have data binding but if we use an ObsevableCollection in the place of List we will see the changes.

Converters

Sometimes the data might not be directly suitable for the data binding. So we might want to need to convert it before it reaches the data binding. So this where the converters come into picture. All Converters in WPF bindings implement the IValueConverter. This interface has a Convert and ConvertBack method. The convertback method gets used in twoway bindings. Converters are very simple. They just get to adjust or replace data that flows between the source and the target.

Let’s see this in action. WE will be using the person class we created earlier. Add the following code to the xaml for the window.

 

WPF Converters

WPF Converters

WPF Converters

WPF Converters

 

And the following code to the code behind file.

 

WPF Converters

WPF Converters

Now create another class in the application named AgeCheckConverter.cs and add the following code to it.

 

WPF Converters

WPF Converters

You will see that we have used this converter in our DataTrigger and checked for value true. The converter does the actual logic and we get the red background if the age is less than 21. Also coverters helps us put the logic for the decision making.

Validation

The data binding system also has support for validation. We can add a set of validation rules for our binding. But to do that we need to use the syntax of binding in full. Validation rules are pretty simple. All they do is look at a value and say whether its valid or not. As we see in the example below the validations will derive from the ValidationRule base class and override the Validate method. You can see the validation rule has no context. It just gets the value. But the problem is that this validation system does not work with the multi field validations. Its more useful at places where we verify whether the strings has the required format or not.

Let’s see this in action. Add a class named MySource.cs and implement the IDataErrorInfo to do the validations.

 

WPF Validation

WPF Validation

Add the following code for the view

 

WPF Validation

WPF Validation

And add the following code behind

 

WPF Validation

WPF Validation

We will see that the textbox border becomes red when a validation error occurs.

 

Other Binding Types

We can also use Multi bindings which lets us combine multiple source values into one result so we can provide it with the connections to ordinary bindings one for each source value and then we need to provide a Multivalue converter that implements IMultiValueConverter.

Another binding is Priority binding which is used by WPF one after another until it finds a binding that works.

 

The Code for the post can be found here.

 

Any Questions, comments and feedback is most welcome.

 

 

Hey guys,

Let’s talk about graphics in WPF. We would talk about the WPF graphics architecture followed by vector graphics, bitmaps and videos, WPF resolution independence and effects provided by WPF.

It might seem interesting to you WPF is built on DirectX 3D rendering engine for all its accelerated 3D rendering pipeline and 2D bitmap rendering. This enables WPF to take the advantage of the modern graphics card engines to a large extent through the Media Integration Layer (MIL). MIL being the unmanaged part helps to make use of the directx to huge extent. Also it helps the main .net (WPF) to communicate with the directx.

WPFDirectX

You should note here that the MIL unmanaged API is not public at the moment but its presence effects the public .NET API. These capabilities allow the user to make use of the graphic capabilities of the modern computers hardware. Now it becomes import for you learn these capabilities so that you could get the best performance out of the WPF graphics.

Transforms

One of the major advantages of WPF is its scalability to support higher resolution for higher DPI screens. WPF provides this facility by providing transform capability to all the elements of the Visual Tree. For example if we apply scale transform to an element in the visual tree then the transform will apply to the node and all its children. This is all taken care by the WPF engine internally so that the developer does not have to worry about all that. You do not need to know anything about the GDI32 or GDI+ to get the work done.

WPF Transforms

WPF Transforms

 

There are several other types of transforms as well that can be applied to WPF elements. These include rotate, translation, scaling and shearing. It does not support perspective transform. If you want the perspective transform then you need to use the WPF 3D features. Now if you would use the rotate transform you would notice that the control is not actually rotated but WPF creates a rectangular bound around the control and use the perpetual effect on win32 to show this transform.

As we would see in the image below we have applied a rotate transform onto the combobox.

 

WPF Transform Combobox

WPF Transform Combobox

The transforms that WPF offers are the ones that we can use to affect the 3X3 transform matrix. These transforms are translate, rotate, skew and scale. To use the perspective transform we need to use the WPF 3D features.

Composition and Integration

Another feature in WPF is to integrate images and media to a WPF application. You can have the video content inside any WPF content control including a button. These kinds of things are really difficult to do in previous version of windows applications. In Win32 overlapping controls are not completely support but in WPF you could have overlapping controls and play around with the opacity of each control. The reason WPF can support such graphics is that WPF has much simpler rendering model. WPF follows the painter algorithm to paint the window. So painting a WPF window is like a painting a picture that means the things you paint later will appear on the surface above the ones painted before.

 

WPF Composition and Integration

WPF Composition and Integration

Procedural vs. Declarative

Declarative style is when you tell the computer what you want and let the computer decide on how to achieve that. The best example to see is SQL, we just tell SQL what results we would like and SQL fetches it for us. But this not quite how the user interface programming works, we need to specify some kind of method that we need to specify which will be called when the element is ready to be displayed. As we can see the code below that we have tapped into the code for OnRender method.

 

WPF Procedural

WPF Procedural

Now let’s use this CustomRender element of ours.

 

WPF Procedural

WPF Procedural

Now before we run this application let’s add a trace to the OnRender method and see how many times WPF makes call to OnRender method. What this trace will do is it will print a message onto the debug window whenever this method is hit.

 

WPF Add Trace

WPF Add Trace

Let’s fill in the additional details.

WPF Add Trace

WPF Add Trace

We will notice that OnRender method is called only once. Let’s see if OnRender is called when we transform the element. Add the following code to the code behind file of the RectangleEllipse.xaml.

 

WPF Rectangle

WPF Rectangle

Now when we run the application and get a scale transform on mouse down, we will see that the OnRender method is still not called. So let’s understand what’s happening here. When OnRender is called the drawingcontext will remember what we asked it to render i.e. a rectangle and an ellipse. It will pass this information to the MIL to perform the actual render. What WPF does is prepares the message with the drawing context of needs to be rendered to the MIL and then MIL renders graphics on its own. So we tell WPF to scale the element what WPF does is passes this message with the details that need to be changed onto the MIL to scale the graphic which was passed to the MIL earlier. And MIL uses the copy of the drawing context to rebuild the new image with the transform. The MIL retains the copy of each drawing associated with each node of the Visual tree.

But this is not the way we generally send the instruction to WPF. Mostly we use the declarative syntax and allow WPF the way it wants to display the graphics. We use XAML here instead of C#. The difference between declarative and procedural programming is that in declarative programming we just define the outcome whereas in Procedural we define the steps we need to follow in order to achieve the desired outcome.

 

WPF Declarative XAML

WPF Declarative XAML

It’s difficult to work with procedural approach and is more error prone. We can achieve the same using declarative syntax in C#.

 

WPF Declarative C#

WPF Declarative C#

Primitives vs. Shapes

In the last example we saw a difference between the procedural and declarative code. In the procedural code we typed Rect whereas in the declarative code we typed Rectangle. This actually represents the difference between the presentation core and the presentation framework. The Presentation Core provides a direct wrapper on top of the MIL. This means that the type Presentation Core uses are fairly close to the types MIL works with. These are generally the simple low level primitive types which do not have a lot of information. We cannot exactly identify Rect on the screen as the same rectangle might be used at 20 different places on the screen.

The types we use in the declarative code are much higher level. It will handle events and we can identify the presence of the rectangle exactly on the screen. The higer level types are derived from the Shape base class and have a much deeper set of services. Also these cost more in terms of resources as a rectangle is a much heavier object than rect struct.

 

The reason for this is that WPF has a split between the Core and Framework. So if we do not need the framework services then we do not need to pay the cost for it and work out with the core type. So the reason for using core type is

  • To increase the performance by reducing the resources required by the object.
  • To use the types to which the framework has not provided any wrapper to like the brushes.
  • Do not need high level types.

But most of the time the higher level types are the first and the best choice.

Basic Brushes

Brushes are the core elements and do not have framework wrapper form them.

We have three types of brushes

  • SolidColorBrush – It is the brush which will uniformly paint the surface of an element. We can also add the transparency effect in this brush. To see this action let’s open the WPF project in Blend and add a couple of rectangles to the canvas overlapping each other. Now give different backgrounds to both of them and set the alpha value of the rectangle above as 50% and we would see something like below.

 

WPF Solid Color Brush

WPF Solid Color Brush

  • LinearGradientBrush – Now let’s add another rectangle and select GradientBrush in the Editor.

 

WPF Linear Gradient Brush

WPF Linear Gradient Brush

Now let’s click the gradient bar to add new stops to add the colors for the gradient brush.

 

WPF Linear Gradient Brush

WPF Linear Gradient Brush

We can also select the brush transform tool to select the direction of gradient.

 

WPF Linear Gradient Brush

WPF Linear Gradient Brush

Now let’s have a look at the xaml for this.

 

WPF Linear Gradient Brush

WPF Linear Gradient Brush

  • RadialGradientBrush – Now when we selected the gradient brush the default was LinearGradientBrush but we can also select a RadialGradientBrush.

 

WPF Radial Gradient Brush

WPF Radial Gradient Brush

Geometries

WPF represents shapes as geometry objects. Geometry is an abstract base class and the most powerful geometry is path Geometry. This defines shapes as a series of figures whose outlines are defined as a series of LineSegment. Let’s a geometry is action. When add the following code to the xaml we do not see a shape but some cryptic text. I will tell you what happened here. Geomerty is path of core API and so they are not allowed in a UI tree directly. We need to pass the geometry to a drawing object or shapes. So whats happened here is that UserControl has figured out that PathGeometry is not a UI element so it has called the ToString on the geometry and displayed the result. SO render this geometry we need to put it into a suitable shape.

 

WPF Geometry

WPF Geometry

Let’s put this geometry into a path and we will be able to see our geometry.

 

WPF Geometry

WPF Geometry

So all the shapes work in a way that they override the OnRender method under the hood and pass the information to the MIL for display. We can tweak the numbers to change the shape. Now let’s see how the multi figure PathGeometry will be displayed. Let’s add a second figure which will remain inside the first figure. We will see something like below.

WPF Geometry

WPF Geometry

So we see a hole in the object which is actually not a hole but WPF does this. When the figures overlap they cancel each other out. WPF counts the number of figures at any point and if the number is odd it fills in the shape and if the number is even WPF leaves it unfilled.

 

WPF Geometry

WPF Geometry

Simple Geometries

The other types of geometries are

  • LineGeometry
  • RectangleGeometry
  • EllipseGeometry

GeometryGroup

Another geometry class is GeometryGroup. It helps us combine multiple geometries into single geometry where each geometry has its own place. Let’s see this on action.

 

WPF Geometry Group

WPF Geometry Group

Path Syntax

When we create a path using the Pen tool in expression blend we will not see anything like PathGeometry in the xaml produced. We will something like shown below. The Data starts with M which means move to this point start the path. Then we have C which is and has four co-ordinates for itself. We keep moving further this way and at the end we will see z which means the end.

 

WPF Path

WPF Path

We can use thin inside any PathGeometry or the data property of the Path. When we represent the geometry as a string it is not represented as a PathGeometry but a StreamGeometry. It does not need to contain the Figures objects.

Drawings

As we saw in the previous section that we had to put the geometry inside a path so that it is rendered properly. But as you might know that Path is a framework element and there are cost involved with its rendering. We not necessarily need a framework element to display our element. Instead we can use WPF drawing structure to display geometries. Drawing is a collection of drawing objects. We can wrap all the drawing objects that MIL can display in a DrawingGroup and using this we can paint geometries, bitmaps, text and videos. The MIL retains the visual representation of all the elements all all nodes of the visual tree so that it can display updates as well and the representation it uses is drawing. So we are talking to MIL in its own language. So this makes drawing the efficient representation in WPF graphics. We do not need to write code to create these drawing as it can be done in XAML. Like geometry dwaring is just a description and does not know how to render itself. So we need to put it inside a DrawingVisual to render it. Let’s see this code. DrawingGroup is at the root of a drawing. DrawingGroup acts as a container for a series of DrawingObjects. We need add this DrawingGroup to the source of an image drawing.

 

WPF Drawings

WPF Drawings

Instead of setting this ImageSource of the image we can set GridBackground of the Grid to DrawingBrush will get the similar effect. This is really good because if we are a lot of framework (above 5000) then we can see a significant drop in the performance. Drawing elements are really useful as they reduce the framework element count and improving the performance of the WPF application. But have to pay cost for using the drawing as from the event handling perspective the whole drawing seems to be one element. Drawings behave like bitmap but these are vector.

Composite Brushes

The drawing brushes that we saw are an example of Composite drawing brushes. They itself contain brushes so we can nested inside another brush and so on. WPF offers another brush named VisualBrush. So rather than using a drawing we can use any VisualTree or Sub Tree as a Visual Brush. Let’ see this in action. We have the fill of the grid to a visual brush. The contents of the grid are a brush but the contents are not interactive.

WPF Composite Brush

WPF Composite Brush

 

TileBrush

All the composite brushes ImageBrush, DrawingBrush and VisualBrush share a base class called a TileBrush. This base class provides properties as below

  • Stretch – This property determines how the content would scale on render. It has values like Fill, None,Uniform,UniformToFill.
  • Viewbox – The Viewbox specifies the source area of interest in an image. So if want only a part if the image we can use as shown below. We can also specify the ViewboxUnits as RelativeToBouindingBox or Absolute pixels. So a Viewbox defines the source material to be used as a brush material. It defaults to relative units.

 

WPF Viewbox

WPF Viewbox

  • Viewport – Viewport defines as to where the source material is projected onto the target. It also defaults to relative units.

 

WPF Viewport

WPF Viewport

Transforms

WPF supports transforms on any part of the visual tree. The transforms supported by Visual Tree are:

  • ScaleTransform
  • TranslateTransform
  • RotateTransform
  • SkewTransform
  • TransformGroup
  • MatrixTransform

We can use them individually or combine them in a transform group. There are two ways in which we can apply transform to a UI element.

  • RenderTransform – This will affect only on the element which it is applied and WPF makes no attempt to reform the layout to accommodate the change in the element.

 

WPF Render Transform

WPF Render Transform

  • LayoutTransform – This will affect the whole visual tree to accommodate the change in the user interface.

 

WPF Layout Transform

WPF Layout Transform

Transform is also a core type and we can apply transform to a drawing or geometry. Also we can apply transform to the brushes as well.

Clipping and OpacityMask

These are the effect that can be applied to any element in the visual tree. We can use geometry to clip any element or we can apply an opacity mask. When we clip an element then anything which is not inside the geometry becomes invisible. WPF anti aliases the border to provide a smooth look. So anything in a clip is clipped with sharp abrupt edge whereas while using the opacity mask we modulate the opacity. Let’s see this in action.

 

WPF Clip

WPF Clip

But this clipping comes with a cost. When we apply clip to a control then WPF renders the entire element into an off screen buffer and then renders the clip result into the main screen. So each element we apply clip to needs an additional buffer.

 

WPF Opacity

WPF Opacity

The same rendering as clip applies to opacity mask as well. It could be even worse as it might end up switching from Hardware acceleration to Software acceleration which might be catastrophic.

Bitmap Effects

WPF also offers a few Bitmap processing effects as well and these can be applied to any element in the visual tree.

  • DropShadowBitmapEffect
  • BlurBitmapEffect
  • EmbossBitmapEffect
  • BevelBitmapEffect
  • OuterGlowBitmapEffect

We can apply multiple effects by using BitmapEffectGroup. In the image below we see a couple of these effects.

 

WPF Bitmap Effect

WPF Bitmap Effect

Animation

In this section we will have a quick look at the services provided by the animation system for dynamic objects. As we can see in the image below we need to specify the trigger which will tell when to start the animation. Here we have an event trigger which will start the animation when this Rectangle.Loaded event occurs. Then we have defined that BeginStoryboard will occur when the specified event is triggered. We can also pause or stop an animation. A storyboard is an orchestration of the steps that the animation will go through. For the demo purpose I have included only one step here. We have also specified the property the animation will change. So the animation type should be corresponding to the specified property. Like below the width property is of type double so we have used DoubleAnimation. We have specified the initial and final values. Also it has the time for the animation will run.

 

WPF Animation

WPF Animation

3D

WPF allows us to incorporate 3d content into our WPF application. The Viewport3D element hosts a 3D model into our WPF application. As the layout only knows about the 2D content so for the layout Viewport is just a rectangle that displays some content. As see in the image below we need to include a 3D camera and a 3D Model will have at least one light and a shape. Generally we will export this 3D model from a 3D design tool. But we can the code below to the xaml file and see how it would look.

 

WPF 3D

WPF 3D

And this how it will appear

WPF 3D

WPF 3D

The code for this post can be found here.

Any questions, comments and feedback are most welcome.

 

Hey guys,

As you would all know that the building blocks of an application are controls but you need to know the layouts as well to know where and how you can place these controls? So we are going to talk about the layout panels in WPF, what are the common layout properties that are offered by WPF and we would also have a look on how to create a navigation application in WPF.

Before we go into what layout panels do WPF has to offer we need to have a look how the layout processing happens in WPF. Now it is obvious that WPF will redo the layout when the applications starts or when something changes on the layout. The layout occurs in two phases: measure and arrange.

In the measure phase WPF walks through the each element in the tree and finds out as how large each element would like to be by calling the method Measure() on each element and it also tries to provide the information as to how much space is likely to available. There are two types of layouts that gets formed: Constrained (when WPF is able to make a good guess of the space that might be available) and unconstrained (When WPF does not have a fair idea of the layout space available). Now elements are not supposed to ask about the space during the measure phase so they just return the preferred size. Also in the unconstrained phase where the size passed is infinity the elements are supposed to return the exact size they require. This sometimes also known as Size To Content.

In the arrange phase WPF calls the arrange method on each element as it now know how much space each element requires. WPF tries to accommodate each elements requirement and if the space provided is less than the controls asked then the controls will be scaled accordingly. But if the element is asking for impossible space then the elements will be cropped.

Declarative Layout

WPF wants us to specify what our requirements are and then in the background WPF does all the work to arrange the resources for it. The best part of it is that it is declarative and can be defined entirely in xaml which can be of course customized as well.

WPF layouts also have the special facilities like automatic resizing according to the space available for the layouts. It also supports dynamic changes that are made to the WPF applications like adaptations to data changes at runtime or locale changes at runtime.

Some of the common layout properties provided by all the layout controls in WPF as Margin, Padding, Horizontal Alignment, Vertical Alignment, Min/Max Width, Min/Max Height, Width, Height. These provide the consistency in the layouts in WPF.

Margin

The margin property helps us determine how much place is there around the space around the edges. Means if you do not want the control to take lesser space then it has been allocated to it so that it does just stick its border along with other controls you could use the margin.

We could specify the Margin as a single value and control will have uniform outer space around it. The unit for the margin is device independent pixels.

Margin in WPF

Margin in WPF

This means that the unit is 1/96th of an inch. So if the margin is specified as 96 pixels then the control will have a space of 1inch around it in theory but in actual this would happen if windows know the resolution of its output device, which is not the case in most cases as most of the windows pc end up in default configuration. If windows does not know the resolution then it will guesses it 96 for 1 inch across. But if windows is using large font sizes then the windows will guess that 120 pixels for 1 inch of the space. So now the WPF unit will be a little larger than the normal pixel. So this is confusing.

We could also specify the Left and Top margin or you could specify the left, top, right and bottom margin specifically.

 

Margin in WPF

Margin in WPF

Padding

The Padding property is similar to margin. As margin specifies the pace outside the control padding specifies the space between the border and content of the control. Padding is not available for all elements as it makes sense for controls that have content. Just like margin padding can be specified as a single number, left and top or explicitly for each left, top, right and bottom.

Alignment

Alignment comes into the picture when the space available for the control is more than required. We can specify the Vertical Alignment or Horizontal Alignment.

 

The default value of Vertical and Horizontal alignment is stretch. So if we specify the horizontal and vertical alignments other than stretch then the control would size to its content depending on the alignments specified.

Content Alignment

Horizontal and Vertical alignments specify how the controls uses the space provided by its container but Horizontal Content Alignment and Vertical Content Alignment determines how the content would align within the control.  Horizontal Content Alignment and Vertical Content Alignment have the same values as Horizontal Alignment and Vertical Alignment and behave quite similarly. The only difference is that it aligns the content instead of the control.

Explicit Height and Width

Most of the times the constrained or the unconstrained size provided to the element do not match your requirements so you could specify the explicit height and width for the control. If you do not want to specify the fixed width and height of then you specify the range by specifying the MinWidth and MinHeight and MaxWidth and MaxHeight.

Grid

WPF provides multiple styles of placing the controls by proving the multiple layout panels. The most flexible of these layouts is the grid. It derives from the panels and provides a row and column layout for placing the controls. For a constrained layouts we could provide the row and column to have autosize or for an unconstrained layout we can specify the specific row or column size values or have a proportional values.

Grid in WPF

Grid in WPF

You could see multiple things in the image above. The use of attached forperties in Button.

The Rows and columns are specified and the rows and columns are sized equally as we not specified any specific size which could be done by specifying the values.

We could also specify the specific height or width of a button and the grid row or columns will be resized accordingly if the space is available for the grid to incorporate the individual requirements for the controls.

 

Grid in WPF

Grid in WPF

We could also set the margin properties and see the effect of these properties within the grid.

 

Grid in WPF

Grid in WPF

You could see the star (*) values used for the height which is relative sizing use. We can have multiple elements in a grid and also elements can span multiple rows or columns. Grid is the default layout element when you create a new vs project.

GridSplitter

You can add a grid splitter to a cell and set the direction and it will resize the columns and rows when dragged.

DockPanel, StackPanel and WrapPanel

WPF also provides DockPanel, WrapPAnel and StcakPanel as a simpler layout panels to work with. There property values are shown in the image below:

 

A StackPanel provides horizontal or vertical stacking of elements whereas a dockpanel provides the alignment as Top, Bottom, Left, Fill and Right and a WrapPanel provides the stacking of elements from left to right and then to new line when the line space is finished.

Canvas

Canvas is the simplest panels. It just places the elements where to tell it to i.e. absolute positioning and will cause the elements to Size to Content. The positions are specified using the Canvas attached properties Top and Right. It can be used at places where you have something like drawing a which you do not want to resize.

ScrollViewer

Another layout control is ScrollViewer. It is not a Panel. It is a Content Control which allows putting control that won’t fit the screen. The Scroll Viewer performs an unconstraint layout and tells the control that it has as much space as it asked for. But this not the actual space, it is the virtual space and the scroll viewer performs the clip and translate transform to show the view of the content. The child does not need to know that it is being scrolled. It is sometimes useful use the scrolls. If you do not want to load the full virtual space initially as it might not be as Performatic. So if you want the control to participate in the scrolling process then if the child element inside the ScrollViewer implements IScrollInfo then the scrollviewer will stop pretending that virtual space is unlimited and will give the control to element for controlling the scrolling.

ViewBox

Like scrollviewer viewbox provides solution fit in content inside a constrained space. But unlike scrollviewer ViewBox scales the content to fit the ViewBox. ViewBox does this for any kind of content like vector graphics, bitmaps or WPF controls.

As you could see in the image below, the Canvas has fixed Width and Height. The reason is that the ViewBox needs to know whats the size of the content so that it can scale and resize it accordingly.

 

ViewBox in WPF

ViewBox in WPF

This works till do not set a stretch property on the ViewBox as it will start adding other behaviors in the ViewBox.

Windows

Window is the main compoanent of any WPF application. It is a Content Control. You can multiple styles in the Window like chrome, borderless or transparent.

There is also the Popup class that is used in Menus, DropDowns and ComboBox. It is also a content Control and can be put custom use.

The third type of Window is Navigation Window and it is slightly different form other windows. The model is quite similar to a web browser i.e. it can be used for navigation from one Page to another as it is built using the Page Class. It has back and forward buttons for navigation. If the Navigation application does not have a Window then the WPF will create the host window and host the page there and provide the navigation controls.

Windows in WPF

Windows in WPF

A frame in WPF is a control that will host the pages and provide the nested navigation area.

The code for this post can be downloaded here
Any questions, feedback and comments are most welcome.