In this section we will talk about Resource handling service of WPF and support for Internationalization

Reusable Resource

WPF provides a resource system for sharing resources. We already used this by using the Resources Properties of a FrameworkElement. Every resource has to have a key as the resource system revolves around dictionaries. The key interface is in the xaml interface defined x:key because xaml has intrinsic support for dictionaries whether it’s WPF, Silverlight or anything else. So the dictionary key attribute lies in the common xaml namespace that lives in all dialogs of xaml. The resource system is used for designing objects for multiple use. It includes templates (factory like objects), graphical resources (especially the ones derived from freezable base class like geometry, transform, brush, etc).

Defining Resources

Below we see example of different types of resources put into the resource dictionary.  We have defined Color, SolidColorBrush, ControlTemplate for Button, ObjectDataProvider, .NET String, Array of strings and Button resources. All the other resources are fine but the button resource that we have added will give us an error when used at more than one place. A button is not built for sharing.

 

WPF Resources

WPF Resources

ResourceDictionary

The resources property is present at various places in WPF. All FrameworkElement and FrameworkContentElement offer it. We can also add resources to the application object, styles and templates. In all the places it is defined the definition is same. It is of type resource dictionary and from the point of view of code it looks like any dictionary object. As it implements IDictionary and it lets us add any object for value and any object for value. In a way the behavior is different from the dictionary and sometime lead to runtime error. Each time we load the ResourceDictionary from XAML then each item xaml gets parsed for the first time it’s fetched. This means the creation of object happens when the key is accessed for the 1st time. So this improves the startup time of the application as the objects that are needed are the ones that are created. The problem is that you might get the xaml loading errors much later than expected so the xaml might seem fine at compile time and might shoot error on loading.

 

Resource References

Xaml provides two markup extensions for using a resource.

  • Static Resource – It is a onetime lookup
  • Dynamic Resource – It works more like data binding. It remember that a particular property is associated with a particular Resource Key and if the object associated with that key should change then dynamic resource will update the target property.

 

Let’s see this in action. So here we have two rectangles which are associated with the same resource SolidColorBrush but one of them uses it as a StaticResource and the other one uses it as a DynamicResource. At the button click we will change the value of the SolidColorBrush and we will see that the Fill property that uses the resource a dynamic resource will change the property.

 

WPF Static Dynamic Resources

WPF Static Dynamic Resources

The difference between these two resources is clearly visible when we see the C# equivalent of these. The StaticResource implementation makes a single call to the FindResource method and sets the element property to the returned value whereas in the DynamicResource implementation is similar to SetBinding call done for DataBinding. Like DataBinding it will detect change and respond to them. As the underlying target property is attached to the reference of the resource. Now it’s obvious that the StaticResource is more lightweight than DynamicResource as it no tracking to do.

 

Resource Hierarchy

Each FrameworkElement in the tree can have its own local ResourceDictionary and that’s the first place where WPF will look for resource. If the resource is not present in the target element’s ResourceDictionary then it will look in the dictionary of the parent and then parent’s parent and so on till the root element followed by the application resources.

 

Whenever we create a WPF application it adds an app.xaml file. This let us configure the application resources.

 

WPF Resource Hierarchy

WPF Resource Hierarchy

WPF provides System level resources. System resources consist of machine wide resources of logon session resources. But that’s not how it’s implemented as WPF is not allowed to share resources across process boundaries. So what happens is each WPF process gets its own copy of the system resources and all these copies are kept in sync across all WPF apps in session. Let’s see this in action. We have set the Fill color of the rectangle to be Highlight color of the SystemColors. But as you see the key for this DynamicResource is a bit different as we have used objects to uniquely identify the resource and these key objects are available as static objects. Also we have one DynamicResource reference and one StaticResource reference. So when we change the system color then we will see that the fill change.

 

WPF Resource Hierarchy

WPF Resource Hierarchy

The SystemResource also contains default styles for controls. This is where the controls get there default appearances from. So we want to override the system resource values then we just need to provide the resources with the same key in our application and we can change the default style of the controls.

Alternate Reference Syntax

Just like all the markup syntax we do not mandatory need to use the curly braces syntax. We can use the property element syntax and spell out the markup extension as a full xml element. I am not sure how much will this be useful as you are using a resource reference at a place where you can’t use an attribute. In the example below we have used a static resource as the content of an element. The important thing to note here is that we need add the resource key through the ResourceKey attribute and normally we use the resource key to the markup extension as a constructor argument.

 

Implicit Resource Usage

Sometimes we use resources without resource key references. If we associate a DataTemplate with a type then WPF uses the ResourceSystem to locate that template. When a control with the ContentModel goes looking for DataTemplate for its Content object it builds a special kind of key object called as the DataTemplateKey to identify DataType and it is this key that is passed to find the resource. If we have added a DataTemplate to the ResourceDictionary in scope then it will find this DatTemplate because DataTemplates are self-keying types. So the key in the resource is hidden but it’s there. Styles also work in a similar fashion. If we specify a target type for a style then we don’t need a key. Also the styles can use the Type as the key. Apart from Style and Data Dictionary if we define any other resource without a key we will get an error.

 

Merging Resources

Most WPF applications end up having a lot of resources and hence the xaml might look cluttered and unmanageable. So WPF Resource System provides a way to merge multiple resource files into a single logical dictionary. The resource dictionary class has a MergedDictionaries property to enable this and we can point this to any number of resource dictionaries.

 

As we already know that we cannot use the same resource key multiple times as it will lead to error. But it works a little differently in ResourceDictionaries. If a resource is not found in one resource dictionary then it is looked for in the next resource dictionary and so on. If the resource is found in one dictionary then WPF stops looking for it no matter whether its present in the other dictionaries or not. This has it pros and cons as you may imagine.

Binary Resources

So we have seen WPF object resources defined in the xaml. WPF also supports binary resources in respect to bitmaps and videos this builds on .NET handling of binary streams. There are 3 ways of handling these binary streams:

  • External – The resource can be completely external to the application like an image on the web accessed with url or an absolute path on disk.
  • Loose – These are the resources that are present in the same directory as executable. These are files that are associated with the application and will be deployed with the application by the installer.
  • Embedded – The resource stream of these resources is embedded inside the exe or dll.

We still need to make a choice between the Embedded and Loose resources.  The exact action depends on the build choice we make. There are 3 common ways to embed an stream as a resource. The oldest and last item on the list is Win32Resource which used by WPF for the icon which is shown in the Windows Explorer. We generally would use Resource or EmbeddedResource as a build action property.

 

Let see these in action. So we have a project with 2 bitmap resources. One marked with build action as a resource and the other one marked with build action as an embedded resource. Now if in the image object in xaml we refer the image file marked as a resource then we are see it.

 

WPF Binary Resources

WPF Binary Resources

But when we use try to access the Embedded resource then WPF is not able to find it. The reason is that embedded resources work differently. TO see what’s going on we need to have a look at ILDASM.

 

WPF Binary Resources

WPF Binary Resources

ILDASM is the disassembler for the .NET code and is part of .NET SDK framework and is used to look at the compiled IL for the assembly. It also shows the information about the resource streams. So when we open the manifest and scroll down we see the mresource part which is the resource stream.

 

WPF Manifest

WPF Manifest

So we see the WPFResources.EbRes.jpg as the resource stream. And the Res.png is in WPFResources.g.resources.

We have accessed this image in the code behind by getting the reference to the assembly then getting the stream of the embedded resource file.

 

WPF Assembly access

WPF Assembly access

So this means the Embedded Resource works but it’s just not supported by image element directly.

Now if we open our application with the reflector we can see our embedded resource and also we will see that we always have a .g.resources file which has the resources and .baml files. Baml is Binary Application Markup Language. It is the Binary Format of the xaml which has the elements, texts, etc. That is how all the WPF xaml ends up i.e. as a compiled baml stream inside the resource collection alongside any resources with Resource BuildAction.

 

.NET Reflector

.NET Reflector

WPF uses the Resource Manager so that we can provide the compiled versions of our xaml files, resource file sin different languages. WPF ResouceManager does that by packaging them up as a satellite assembly and then deploying them next to our application. So WPF prefers to use the WPF Resource BuildAction.

So below we can see the examples of the WPF Image Resource Uses.

 

Application Class Resource Methods

WPF Application class provides some helper methods to work with the resources.SO if want to get a stream in the application then we are supposed to use the Application.GetResourceStream method. And use GetContentStream for loose resources and GetRemoteStream for remote resources. We use these helper so that we do not raise any security exceptions in the limited access application. So we should use these helper when we need direct access to the resources. Another helper LoadComponent is used for compiled xaml. As we already know that xaml is compiled to baml. We should also remember that all .NET applications use LoadComponent to load this baml.

 

Themes

WPF support for VisualStyles or Themes lies in the concepts we have been looking at. These are resources that are compiled as resources as compiled baml streams. According to naming conventions their names all start with Themes\ and the resource streams will be compiled into the folder called themes and then we have one compiled xaml stream for themes. As we can see in the image below

 

WPF Themes

WPF Themes

All the controls provide themes in this way. WPF controls do it this way and custom controls do it this way and these resource strings just get added to the system resource scope. WPF selects the appropriate resource stream based on the theme we are running and just merges its content into the resource scope. If we do not have resources matching the current theme then WPF will look for Generic.xaml as a fallback. That’s where the control library will put a set of resources in the event the user is using a theme that the control did not know about.

Internationalization

Internationalization depends entirely on the resource manager. If we want to localize an application for a particular culture then we need to provide a satellite resource assembly for that locale which contains the resource stream with the suitably compiled version of the xaml.

The process that is followed is that the Code behind calls the InitializeComponent() which in turn calls application.LoadComponent. LoadComponent will then use the ResourceManager Infrastructure to load up the baml stream and the ResourceManager always checks to see if the satellite resource assembly exists of the current locale. If the suitable assembly is present then it will look into the resources to see if it contains the localized version of the baml. And if it does then that baml will be used instead of the one compiled into the main assembly. SO localize the application we need to make the necessary changes to the xaml and the compile that to the satellite resource assembly and then deploy that to the appropriate sub directory for the culture and that’s all. But in practice we will not have a xaml file for each language so we will have one master xaml and then derive the xaml for individual languages from that.

So the runtime model is different from the production model. So at runtime there is a compiled version of a xaml file for each language and at runtime we try to have one master file  and then generate the different files from that.

 

Localization Workflow

WPF provide tools to support a particular workflow to the localized resources of the application. We will start with one Unlocalized for the XAML resource. The first that we need to do is add Uid annotations which provide an unambiguous name to each element. As we have already observed xaml elements may already have names so why do we need another one. The reason is that xaml x: namespace has 2 problems:

  • It’s optional
  • It’s not necessarily unique

So it’s easier to have unique names just for the purpose of localization. WE can add matching Uid with WPF build targets so that MS build can modify the files for us adding the necessary uids.

Then we build the project as normal producing the binary with embedded compiled xaml.

Then we run a tool to extract all the information that may need to change for localization purposes. The tool that Microsoft provides puts it into a csv file. That is a , separated value file. Also we can modify the tool to configure the way we want to use the tool.

Then we work out what needs to be changes for our target culture and make a list of the same.  Again the MS tools work with the csv representation but we can modify the tools.

Then we can use this to produce the localized version by running it against the tool that sees the differences and generates the files.

So the output is a satellite assembly which can be deployed alongside the executable.

 

 

LocBaml

The tool provided by Microsoft to support this is called LocBaml. We actually have to build it ourselves as it is a sample in the sdk. So it does everything the code supports. It uses documented API .So the process is supported even if the tool is semi efficient. As localization tends to be somewhat specialized operation a lot of companies rely on external companies to do the translation. But WPF aims to provide the mechanism rather than the tools to do the localization.

It is not necessary that we follow the same workflow provided by LocBaml. We can use DataBinding for this purpose as well.

XAML presumes that UTF is the default.

Any questions, comments and feedback are most welcome.

The code for this post can be found here.

 

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.