Tag Archives: WPF

WPF internals part 1 : what are the core WPF classes ?

In this first article, I’d like to make a tour of the core WPF classes and how they are related.

Knowing the organization of WPF classes is important when we create a new control because we have to determine which base class we’re going to use. It is also interesting to know how the framework has been designed. That’s the goal of this first article.

Here is an image of the core WPF classes and how they are related (click for larger resolution):

The diagram is voluntary simple above the Control classes because that will be targeted by another article.

The top level class DispatcherObject:

  • represents an object that is associated with a Dispatcher
  • can be accessed from a thread other than the thread the DispatcherObject was created on, using Invoke or BeginInvoke calls
  • can enforce thread safety by calling VerifyAccess
  • cannot be independently instantiated; that is, all constructors are protected

From the DispatcherObject class, we have 4 new classes (one more time, this is a partial view of what really is in the framework):

The DependencyObject class:

  • contains the mechanism to deal with Dependency Properties through a set of methods such as ClearValue, SetValue and GetValue
  • is inherited by 3 new classes
    • TriggerBase, for specifying a conditional value within a Style object. Inherited by DataTrigger, EventTrigger
    • Freezable, for object that has a modifiable state and a read-only (frozen) state. Classes that derive from Freezable provide detailed change notification, can be made immutable, and can clone themselves
    • and the Visual class,

The Visual class:

  • provides rendering support in WPF, which includes hit testing, coordinate transformation, and bounding box calculations
  • is the first class supporting the VisualParent property that helps setting up the visual tree
  • support methods for adding, removing and getting visual child (through the IAddChild interface)
  • has an VisualEffect property of type Effect (from Animatable / Freezable)
  • is inherited by the UIElement class,

The UIElement class:

  • can render as a child element
  • contains logic that is used to size and position possible child elements of a UIElement (when interpreted by a layout system)
  • can respond to user input (including control of where input is getting sent to via their handling of event routing, or routing of commands)
  • can raise routed events that travel a route through the logical element tree
  • supports some aspects of the animation system
  • is enhanced by the FrameworkElement class,

The FrameworkElement class extends the UIElement class by adding the following functionalities:

  • layout system definition using the ArrangeOverride method
  • logical tree with the Parent property
  • object lifetime events such as Initialized, Loaded, Unloaded
  • support for databinding (DataContext property) and resources management (Resources property)
  • support styles (Style property)
  • does not handle the Template feature implemented in the Control class

Several classes inherit the FrameworkElement class:

The Control class:

  • is the base class for WPF controls that use a ControlTemplate to define their appearance (through the Template property)
  • defines a set of UI properties (that can be exploited by ControlTemplates): Background, BorderBrush, BorderThickness, FontFamily, FontSize, FontStrech, FontStyle, FontWeight, Foreground and Padding
  • support mouse double clicks event using MouseDoubleClick and PreviewMouseDoubleClick

In order to show where most of the WPF controls are (but that will be the object of another article), I also added ContentControl, ItemsControl, UserControl and Window class to the diagram.

The cost of building Visual Trees

In the current project I’m working on, I’m designing a diagramming component. Of course because it’s for work I can’t release the source code (however if you want a good starting point you can check out this article). Designing such a component is a challenging task and there are a number of things I learned during the last few months that I’m glad to share here.

As you problably know the WPF engine manages 2 trees: the logical tree and the visual tree. For each logical item (that you declare in the XAML), the item is expanded with its visual tree (for example, a scrollbar is made of RepeatButtons and a Thumb). To visualize the visual tree you can use a tool like snoop.

In a diagramming tool, you might want to draw lines betweeen entities, like the following:

connection

In this article, we’re going to talk about the underlying control that we can use to do that. If you need to create that kind of control, you basically have 2 options:

  • inherits from Control and override the OnRender method to do the basic graphic operations (such as drawing a line or an ellipse)
  • inherits from Control and create a ControlTemplate to fill the visual tree of your control

Of course the first option has better performance, but it’s also less evolutive. Moreover, in the OnRender method, you can only do low level graphic operations.

Using the second option is generally fine and easy:

  1. create the class that inherit from Control
  2. create a style that targets your new control
  3. add a Setter to set the ControlTemplate property
  4. fill the ControlTemplate’s content

Here is a sample ControlTemplate for a basic connection (assuming that the Connection class has 4 double dependency properties (X1,Y1) (X2,Y2) that defines that start and the end point):


Of course this is a very minimal template, you’re probable going to improve it by adding new features:

  • 2 rectangles to show the extremities of the connection
  • 2 thumb to be able to drag’n’drop the extremities
  • 1 context menu to access connection’s operations

You can do that by adding more controls to the template. Now, take a second and think about the performances. Time is needed to built and render the visual tree and the most complex it is, the longer it takes. I did a quick benchmark on my machine and here are the results for 500 connections added in a Canvas:

performance

What we can see is that adding only 5 controls in the template, we multiply the rendering time by 4 ! That means we must be careful when we’re designing ControlTemplate that are going to be instantiated many time. Before creating the control we should think about whether the control is going to by displayed 1, 10, 100 or 1000 times in our application. More complex ControlTemplates mean more time to render them. Several techniques can be used to improved performance:

  • use a panel that supports UI virtualization (such a VirtualizingStackPanel)
  • use adorners to give feedback while an item is selected to improve creation performance (create the Adorner only when the item is selected)

To explore other performance related techniques:

How to close a View from a ViewModel ?

Note: I wrote this article to clarify relationships between ViewModel and View classes. If you want a complete solution you should take a look at existing MVVM framework like Cinch (by Sacha Barber).

Yesterday, there was an insteresting question about MVVM on StackOverflow: “How to close a View from a ViewModel ?”

Like always with WPF, there are many approaches to solve this problem.

Solution 1: give a reference to the View in the ViewModel

You need to control the View from the ViewModel ? Just gives a reference to the View in the ViewModel constructor.

public Window1()
{
  this.DataContext = new Window1ViewModel(this);
}

Unfortunatelly, this approach has several drawbacks:

  • it breaks the foundamental principle of the MVVM methodology: the ViewModel should be an abstraction of the View
  • it complicates the work needed to unit test your ViewModel
  • it introduces high coupling between the ViewModel and the View

Solution 2: the ViewModel raises an event when it wants to close its associated View

If having a reference to the View in the ViewModel is not the right thing, why not using an event. We can add a RequestClose event in the ViewModel class and raise this event when the ViewModel wants to close its associated View.

The View, when it creates the ViewModel subscribe to the RequestClose event. In the event handler, the View is closed.

// class is omitted, only constructor is shown
public Window1()
{
  var viewmodel = new Window1ViewModel();
  viewmodel.RequestClose += (s, e) => this.Close();

  this.DataContext = viewmodel;
}

Solution 2, first refinement

Of course I prefer the event based solution, but we can improve it. The first refinement we can do is to make sure the event will be coherent over all our classes. To achieve this I setup an interface:

public interface IRequestCloseViewModel
{
  event EventHandler RequestClose
}

This interface is implemented by my ViewModel classes which wants to support the ability to close their associated Views.

Solution 3, second refinement

Another possible refinement is to automate the subscription of the RequestClose event in the View. To do that, I created an abstract ApplicationWindowBase class that inherits from Window. When the DataContext changes, I check if the IRequestCloseViewModel is supported by the DataContext:

public class ApplicationWindowBase : Window
{
  public ApplicationWindowBase()
  {
    this.DataContextChanged += new DependencyPropertyChangedEventHandler(this.OnDataContextChanged);
  }

  private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
  {
    if (e.NewValue is IRequestCloseViewModel)
    {
      // if the new datacontext supports the IRequestCloseViewModel we can use
      // the event to be notified when the associated viewmodel wants to close
      // the window
      ((IRequestCloseViewModel)e.NewValue).RequestClose += (s, e) => this.Close();
    }
  }
}

Like I said in the intro, this a very basic implementation of this concept. Many other approach exists. A good source of information is in the source code of existing MVVM frameworks.