What's new in WPF in .NET 3.5?

This is the first list I’ve seen that covers the new features being added to WPF in .NET 3.5. Top three things that stand out to me:

  1. Binding support for LINQ based data sources
  2. UIElement3D – adds support for input and focus events to 3D elements (finally, no more hand crafting!)
  3. Viewport2DVisual3D – enables you to paint 3D surfaces with interactive 2D elements. This was a sorely missed feature from 3.0 that appeared as an open source project later and has now been folded into the actual WPF API as a first class citizen.

A Rebuttal Of Mr. Grimes' Avalon -> Win32 Ties Accusation

I’m sure we’ve all seen Richard’s commentary on the state of .NET as well as Dan Fernandez’s rebuttal. If not, go read those first. Since the subject has already been talked to death from the .NET framework perspective, the only thing that I wanted to address is the assertion that Richard makes in his follow up comment in Dan’s rebuttal where he states:

As to your comments on Avalon and Indigo. I concede your point about Indigo, but I refute your point about Avalon. In Dec 2004 a tech preview of Avalon was made publicly available on MSDN downloads, and by examining this with ildasm it is clear to me that Avalon is yet another wrapper over Win32. Avalon is based on Windows messages, and uses GetMessage, DispatchMessage et al, that Windows developers have been comfortable with since 16 bit Windows!

First off, Richard’s absolutely right, there are all kinds of calls to Win32 messaging APIs in the Avalon CTP. However, the important thing to realize is that none of this is exposed via the Avalon API itself. Of course there needs to be calls to Win32 APIs under the covers, this is just how things get done on Win32. Therefore, backporting Avalon to Win32 meant that some things had to be accounted for and handled using the existing platform’s plumbing. Why do we care how Avalon is implemented under the covers so long as those details are hidden from us? If I can write an Avalon application that runs on Win32 just as good as it will run on WinXXX three to five years from now, who cares what they do to preserve that?

Let’s examine the one specific area which demonstrates Avalon’s abstraction from the underlying OS: the UIDispatcher class. The UIDispatcher class’ job is to dispatch messages received from the underlying OS to the UIContext for a particular Avalon application. Now obviously in Win32, these messages need to be handled via a message pump, so there is a specific implementation of a UIDispatcher called the Win32Dispatcher (go figure). More specifically, if you’re writing an Avalon application that is going to use WinForms controls (or any windows controls really) you need to go one step further and use the HwndDispatcher. Oh and by the way, this is also the piece that enables the reverse scenario: Avalon controls hosted in legacy Windows/WinForms applications. The key to this part of the API though is that this is the piece where things get translated from native OS messages to strongly typed Avalon events. Beyond Win32Dispatcher, there is no such thing as a Win32 style message.

Next let’s examine the most obvious dependency of Avalon: DirectX. Under the covers, Avalon is making heavy use of the DirectX API in order to achieve its rendering goals. This is another area where there is there is just zero leakage in the API. As an Avalon programmer working at almost the deepest depths of the graphics plumbing in the API I see no signs of DirectX whatsoever. What does this mean? It means that once again Avalon could technically run on any graphics API under the covers. It happens to be DirectX9 right now, but whenever DirectX10 rolls out the Avalon team could also roll out some optimizations to the Avalon API which take advantage of that version without my application being any wiser.

So, is this a bad thing? If so, I just don’t see it. What this really means to me is that they’re doing an excellent job separating Avalon from any one underlying architecture and, in fact, enabling it to run optimally on any architectures they introduce down the line with very little work and almost zero changes to existing applications. The reason we’re at the point where Avalon is even being built on these “older” architectures, as has already been mentioned, is because customers were demanding it and Microsoft actually listened.

Avalon: Understanding DependencyObject and DependencyProperty

I’m writing this article in response to a
newsgroup posting
where the reader states:

I am confused by this concept : why it is designed like this? Is
there any document on it’s design purpose and intention? The document in Avalon
CTP is not helpful.

I’m sure a lot of people either are, or will be, wondering the
same things, so I figured I would whip together this article for future
reference.


The
DependencyObject
/
DependencyProperty
design actually exists for several reasons all of
which I’ll ultimately touch on within this article, but let’s start with one of
the main concepts for which this design exists known as “attached properties”.
You’ll encounter the concept of attached properties almost immediately as you
start to use Avalon. Attached properties are dependency properties that other
classes declare that can then be applied to any class you will ever throw into
the Avalon mix. Let’s look at one of the simplest examples of attached
properties which involves positioning an item on a
Canvas
. Canvas has four dependency properties regarding positioning:
TopProperty, BottomProperty, LeftProperty and RightProperty. Now, let’s say we
want to just throw a random UI element onto a Canvas. That UI element’s class
has no prior knowledge of the existence of the Canvas class or how it chooses
to position the elements it contains. Therefore, when I want to put that UI
element “into” a Canvas, I need to decorate it with Canvas specific dependency
properties to get it to lay out correctly.

Right about now you’re probably thinking “Well why not just have
base class for all UI elements with Top, Bottom, Left and Right properties?”.
Well the answer to that is simple if you consider a different layout container
such as the
Grid
. The Grid doesn’t just layout things at a certain static X,Y
coordinate like the Canvas. It uses rows and columns and automagically
positions contained elements based on all the contents of the columns (for X)
and rows (for Y). So, to accomplish this, the Grid offers the following
dependency properties for positioning instead1: ColumnProperty and
RowProperty.

So the next question is: How do these properties get applied to
arbitrary classes? Well first off, the classes obviously need to be
DependencyObject subclasses. From the consumer point of view, DependencyObject
is little more than a glorified Hashtable2. It’s job is to store the
current values of any DependencyProperty that is ever applied to it. Setting a
dependency property is simple:

// Create a button
Button myButton = new Button();

// Button ultimately derives from DependencyObject, so let's set
// some properties so that it can be positioned on a Canvas!
myButton.SetValue(Canvas.TopProperty, new Length(100, UnitType.Pixel));
myButton.SetValue(Canvas.LeftProperty, new Length(100, UnitType.Pixel));

// Add the button to a canvas and it will be positioned at 100,100
myCanvas.Children.Add(myButton);

Actually, you know what? That’s the long winded version because
Microsoft has defined a well-known pattern for manipulating attched properties

that make it a little easier for us. The pattern basically says that the class
that owns the dependency property should provide static accessor methods to
get/set the value on arbitrary DependencyObject instances. So let’s look at
that version:

Button myButton = new Button();

Canvas.SetTop(myButton, new Length(100, UnitType.Pixel));
Canvas.SetLeft(myButton, new Length(100, UnitType.Pixel));

myCanvas.Children.Add(myButton);

Hmmm… wait, that’s a long winded version too!!! Why write any
C# at all? Let’s see how this pans out in XAML!

<Canvas ID="myCanvas" xmlns="http://schemas.microsoft.com/2003/xaml">
  <Button ID="myButton" Canvas.Top="100" Canvas.Left="100"/>
</Canvas>

Remember that pattern I just mentioned? Well XAML relies on it
and translates the Canvas.Top attribute syntax to a Canvas.SetTop call.

Ok, this all seems simple enough now that we’ve been introduced
to it right? So, what’s the big deal? Well, wait… we’ve only scratched the
surface with the introduction of attached properties. Attached properties
aren’t the only place that dependency properties should be used. I
just decided to started with them because they demonstrate one of the key
features that DependencyObject enables, which is the ability to tack
infinite amounts of data onto existing objects without them ever having to know
about it in the first place. So, let’s look at a simpler scenario for
dependency properties now, the
Canvas.HeightProperty
. This could have easily been designed as a plain
vanilla .NET instance property of type Length
on the Canvas class and nobody else will ever apply this property to
anything but a Canvas, so why go through the trouble of making it a dependency
property? Point of fact, it still does appear as an
instance property on the Cavas class, but the reason it’s defined as
a dependency property is simple: to gain generic support from Avalon
in terms of services. The “big deal” once you use dependency
properties is that Avalon can also offer many services to your
DependencyObject subclasses now without having to know about their custom
implementation details (in this case Canvas.Height
). Perhaps the easiest service to demonstrate, which is probably also the most
prominent in Avalon, is
animation
. Any dependency property can be animated. Let’s take that
sample we’ve been working with and animate the attached property a little
bit:

<Canvas ID="myCanvas" xmlns="http://schemas.microsoft.com/2003/xaml">
  <Button ID="myButton" Canvas.Left="100">
    <Canvas.Top>
      <LengthAnimation From="0" To="100" Duration="2"
         RepeatDuration="Indefinite" AutoReverse="True"/>
    </Canvas.Top>
  </Button>
</Canvas>

This will animate the button up and down from 0 to 100 (pixels)
over a two second period. Now admittedly, I probably wouldn’t want to animate
the position of a Button in the real world, but that’s actually the point that
I’m driving at. This could just as easily be a Rectangle or another Canvas or
even my own custom control! The positioning of the element on the Canvas
and animation of it’s properties is done exactly the same way for any
DependencyObject subclass that is ever written from now until eternity.

Ok, ok… I can hear the masses screamning: “Bah! Animation, who
needs it!?”. Fine, fine… what about the rest of these services that are based
on dependency properties then?

Service Description
Default
Values
Provides abillity to set the default value for anyone who uses a
particular dependency property in one location (see
PropertyMetaData.DefaultValue
)
Expressions Provide the ability to base a dependency property on a calculated
value instead of a constant (those familiar with IE’s CSS expression support
already have a head start on this one). Perhaps the coolest part of expressions
is that you can write your own calculation logic quite easily by simply
deriving from
Expression
Databinding Actually implemented as an Expression, provides the ability
to bind data from various sources to our property values.
Inheritance For those familiar with CSS, this is the cascading aspect of
something like a font style being applied to the of your HTML document applying
to all descendant elements without explicit font style declarations of their
own
Styling A
Style
in Avalon is basically3 a declaration of a set of
dependency property values
Property
Invalidation
Avalon strongly encourages the concept of dependency property
caching for performance reasons4, property invalidation is the act
of notifying the caching class that it’s local, cached version is no longer
valid

So, that’s it! Hopefully this article helps you
to understand the necessary level complexity that is introduced by the
DependencyObject/DependencyProperty model. Without
DependencyObject/DependencyProperty, the only way to achevie the same type of
generic behavior in .NET would be through something like reflection
which we all know has serious performance side-effects. The design enables
infinite levels of extensibility and provides powerful services for your
custom classes which allow other developers to use them in ways that you
may never have even imagined.

1 Grid is more
complex than this, but for purposes of this example this is all that is needed
to undersand.
2 In actuality, the design of DependencyObject is more complex with
great consideration for performance.
3 A style can actually get quite a bit more advanced when it defines
a VisualTree
4 For more on cached properties,
check out this section of the SDK