Enable ElementName Bindings with ElementSpy

July 22, 2008

There are some situations in WPF where the ElementName property of a Binding is useless.  One common example of this is when you try to perform an ElementName binding on elements in a tooltip.  WPF manages to pump an inherited DataContext into the elements in a tooltip, but it does not add a tooltip to a namescope, so you cannot use ElementName in their bindings.

If you try to use an ElementName binding on a tooltip element, the Output window will display this type of debugging info:

System.Windows.Data Error: 4 : Cannot find source for binding with reference ‘ElementName={0}’. BindingExpression:Path={1}; DataItem=null; target element is ‘{2}’ (Name=”); target property is ‘{3}’ (type ‘{4}’)

There have been some workarounds posted, such as the excellent approach that Andrew Smith posted shortly after we discussed this very issue.  His approach involves a custom implementation of INameScope that traverses the element tree to find a namescope to apply to a tooltip.  There is also the idea of binding to the ToolTip’s PlacementTarget, which still does not give you a functioning ElementName binding, but does allow you to bind to a certain element.  This blog post introduces yet another utility class that leverages the Hillberg Freezable Trick to gain access to an inheritance context from an object added to a resource dictionary.  This is similar to my DataContextSpy, only its purpose is a bit different.  ElementSpy, the new class, provides two ways to enable you to bind to any element in the element tree, from any element that is not able to use ElementName bindings (such as elements in a tooltip).

It is important to note that ElementSpy relies on the use of reflection, so it cannot be used in a partial trust application, such as a standard XBAP.

The ElementSpy class exposes two public properties, Element and NameScopeSource.  Element is a read-only property that returns the element in whose Resources collection the ElementSpy is placed.  You should only put an ElementSpy into one element’s Resources and once it is in a Resources collection, you should not remove it and add it to another element’s Resources.  Here is the Element property.

As mentioned above, the ElementSpy class relies on reflection to get at its InheritanceContext, which is an internal property of Freezable (which is ElementSpy’s base class).   If you have a policy that prohibits the use of reflection to coerce .NET into bending to your wills, you obviously cannot use this class.  When a Freezable, such as ElementSpy, is placed into an element’s Resources collection, the InheritanceContext property is set to that containing element.

The other property is an attached property called NameScopeSource.  That property allows you to assign an element the NameScope that was assigned to the element that contains an ElementSpy.  This property is a tad more confusing than the Element property, but, as we will soon see, it has very strong advantages.  Here is the property definition:

Now let’s see this in use.  The demo app looks like this:

The key point to notice is that the tooltip of the TextBlock displays information taken from properties of the Window.  This is achieved via ElementName bindings.  The beginning of the Window’s XAML looks like this:

It is important to note that we add the ElementSpy to the Window’s Resources, because we want it to “spy on” the Window.  Whatever element’s Resources collection an ElementSpy is added to will be the element returned by the spy’s Element property.  Now let’s see how the upper TextBlock in the demo app uses the Element property to bind its tooltip elements to the Window:

The key is that we reference the ElementSpy as a resource (in this case, a StaticResource) via the binding’s Source property.  Also, the binding’s Path includes the Element property.  ElementSpy exposes that property, which returns whatever element the ElementSpy happens to live in the Resources collection of.  In this example, the Element property returns the demo Window.

Now let’s see how to use the attached NameScopeSource property.  Setting this property once enables multiple elements to use ElementName bindings.  Here is the lower TextBlock in the demo app:

As seen in the XAML above, using the NameScopeSource property enables true use of ElementName bindings.  This works because we are assigning the root TextBlock of the tooltip the same NameScope assigned to the Window.  Since the Window is in that scope and has an x:Name of “window”, the elements in the tooltip are able to find the Window via ElementName binding.

Download the source code here: Element Spy Demo .  Be sure to rename the file extension from .DOC to .ZIP and then decompress the file.


Catalogue of Artificial Inheritance Context Techniques

July 2, 2008

I spent my lunch break today publishing an article that I’ve been working on for a couple of days. It explains and shows examples of three techniques I have developed for creating an artificial inheritance context.  This is useful for binding elements that are not in an element tree to the elements in the tree. If you are interested in checking it out, read “Artificial Inheritance Contexts in WPF“.

Enjoy!


DataContextSpy

June 26, 2008

I just blogged about my new DataContextSpy class, over on my other blog. It uses Hillberg’s Freezable trick to gain access to an inheritance context from an object that is not in a logical tree. DataContextSpy is very simple, so it should be reusable in many scenarios.

I hope eventually Microsoft provides a first-class addition to WPF that makes it easy to create an artificial inheritance context. Having to rely on that strange aspect of Freezable is kinda…

LAME!

…though it’s great to have in the toolbox. ;)


Allowing CommandManager to query your ICommand objects

June 17, 2008

One of the great parts about commands in WPF is that they know if they can currently execute or not. When they cannot execute, the control(s) that are set to execute the command will be disabled automatically. For example, if your application has no changed data, the Save toolbar button will automatically be disabled, assuming its Command property is set to the Save command.

WPF will automatically ask all of the commands being used in your UI if they can execute. This happens at various times, such as when input focus shifts to another control, an item is selected in a list, etc. You can also programmatically trigger this to happen by calling the CommandManager’s InvalidateRequerySuggested static method. This all seems magical, dreamy, and almost too good to be true.

Here’s the hitch: this beautiful system of commands automatically notifying the UI that they cannot execute only works out-of-the-box for RoutedCommands. If you simply implement ICommand and hook up, say, a Button’s Command property to reference that non-routed command, suddenly the Magical Love Machine comes to a grinding and screeching halt. Why? Because by default WPF has no idea that your custom ICommand objects exist. How would it?

Fortunately there is an easy solution to this problem. In your ICommand implementation, you make the CanExecuteChanged event hook the CommandManager’s RequerySuggested event. I lifted this little trick straight from Reflector, as I perused the RoutedCommand class…

class MyCommand : ICommand
{
public bool CanExecute(object parameter)
{
return maybeTrueOrFalse;
}

public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}

public void Execute(object parameter)
{
// Do something awesome.
}
}


Post about unbound fields in XamDataGrid

June 16, 2008

If you use the Infragistics XamDataGrid, you might want to check out my latest post about it.  I put together a demo app that shows the proper way to embed controls into unbound fields, and react to the user interacting with them.  Here’s the obligatory screenshot…


Understanding Templates in WPF

June 15, 2008

If you are versed in the ways of Windows Forms and plan on using WPF, brace yourself. The platform might seem somewhat similar at first glance. After that brief initial survey, the landscape changes dramatically. In my opinion, the primary differentiator is the fact that WPF makes heavy of use of something that does not even enter the mental landscape of WinForms. I am talking about templates.

As I explained in the fourth entry of my guided tour of WPF, templates are like a cookie-cutter. Instead of resulting in delicious baked goods, these cookie-cutters produce a tree of visual elements that can render something. What can they render? Anything.

Coming from a background in ASP.NET this concept might seem entirely natural, since the ASP.NET platform has used templates for years. The Repeater control, for example, makes heavy of templates. The WPF ItemsControl is the moral equivalent of Repeater, in that it produces a static list of items based on a description of visual elements declared in markup.

In WPF there are several types of templates that you use often. They all derive from the abstract FrameworkTemplate class. DataTemplate is used to create a visualization of a non-visual object, such as a business object. ControlTemplate supplies a visual representation of a UI control, such as a Button or ListView. ItemsControl, and all of its subclasses (such as ListBox), create the layout panel that hosts their child elements via an ItemsPanelTemplate. Another commonly used template in WPF is the HierarchicalDataTemplate, which is a data template that has knowledge of how to display a data object’s child objects, such as in a master-detail situation.

The mental shift that I had to make, when leaving WinForms and entering WPF, is that a UI is made of templates. Forget about building a UI and then shoving data into it. That’s not the WPF way. In WPF we show data in a user interface, instead of showing a user interface that contains data. It is a subtle, yet crucial, distinction. If you find yourself creating a UI in WPF and then filling it with data, you are not doing things the WPF way. If you find yourself seeing the UI as a mere “outfit” that data “wears” then you are on the right track. At least, that’s my opinion.


Writing XAML that gracefully degrades in partial trust scenarios

June 12, 2008

Developing WPF applications that run with full trust allows you to remain blissfully unaware of the problems involved with working in a partial trust environment. Once you begin to take the limitations of running in partial trust into account, life becomes more complicated (and more full of headaches). This blog post shows a utility class I made, called IfFullTrustExtension, which helps to create XAML files that work well in both trust environments.

Recently at work, I inherited an application that runs both as full trust and as partial trust. It runs under full trust when deployed as a desktop application, and partial trust when deployed as an XBAP. The Visual Designer I was working with made some excellent looking UI assets in Blend, but they were causing problems when running in the XBAP because they made use of bitmap effects. Bitmap effects have a history of not working in partial trust because they rely on unmanaged code and, thus, require UIPermissions to be instantiated. I really liked how those effects made the Designer’s UI assets look, but didn’t want to get into the messy business of applying those bitmap effects in code.

I needed a way to conditionally apply bitmap effects to elements in XAML. I slept on it, and when I woke up this morning, I had the following solution in mind…

The real problem here is that you cannot instantiate a bitmap effect class if you are running in partial trust. Since XAML has no inherent concept of “trust,” I needed to introduce it. I also needed to provide a way to conditionally instantiate objects declared in XAML, based on the level of trust given to the app by the CLR. This resulted in my new IfFullTrust markup extension, as seen below:

Using the markup extension in XAML looks like this:

Note that the DropShadowBitmapEffect XAML is in a CDATA block, and the default XML namespace is mapped to the standard WPF default namespace. Since the XAML is in a CDATA block, the bitmap effect will not be instantiated when the Page loads, but the XML it contains will remain intact so that my markup extension can read it.

If you run this XBAP project with full trust, it looks like this:

Notice that the drop shadow appears, as expected. The screenshot below shows how to make the XBAP run in partial trust, which is the default (and recommended) configuration for an XBAP:

If you run the app now, no exception is thrown and the app runs just fine. But, as seen below, there is no drop shadow:

[EDIT]

After posting this, I found that Andrew Smith had already blogged another, though different, use of markup extensions to work with bitmap effects.  His technique is described here.  My markup extension is not specific to working with bitmap effects, but his has the advantage of having the XAML be verified by the compiler.

[/EDIT]

Download the source code here. NOTE: Be sure to change the file extension from .DOC to .ZIP and then decompress it.


Yet another workaround for not having an inheritance context

June 5, 2008

There are several workarounds for the fact that you can’t give any arbitrary object an inheritance context (i.e. data bind the properties of any object to stuff in the WPF element tree), such as my virtual branch technique, and Hillberg’s Freezable approach. I recently came up with yet another, not-so-elegant, approach that I like to call GHETTO-INJECTION.


Joe Rattz to the Rescue

April 24, 2008

In my previous post, I showed a simple way to create animations in WPF using a sequence of images. That demo app used a LINQ query to get a sequence of BitmapImage objects based on the PNG files in a certain folder. Joe Rattz, the LINQ guru, dropped a comment on that post and also included his e-mail address. Big mistake!! :D

I sent him an e-mail, asking if the BitmapImage objects in that LINQ query are created every time a new enumerator is created and iterated over. When I send an expert an e-mail I never expect to hear back. I certainly don’t reply to all of the questions that people send me! There are only 24 hours in a day. :P

Luckily, Joe replied. Thanks Joe! It turns out that the answer is yes, the LINQ query is creating new BitmapImage objects for each new enumerator, as the enumerator is iterated. This is not a good thing. Since my demo app repeats the animation indefinitely, a potentially huge number of unnecessary BitmapImage objects were being created by the LINQ query.

The reason for all this is the fact that my LINQ query was only using deferred query operators. LINQ has deferred and non-deferred operators, as Joe’s book explains. If you use all deferred operators, the query’s results are not cached. Every time you iterate the resultset the query creates new objects for you. In some cases that is what you want. In my case, it is undesirable.

Working around this turned out to be easy, especially since Joe e-mailed me the answer. ;)

I needed to apply a non-deferred operator to the query. This would cause the results of the query to be cached, so that all enumerators created against the query iterate the same set of objects. Here is the new code-behind for the demo app:

Notice how the entire LINQ query is wrapped in parenthesis and then a call to the ToList extension method is placed at the end. ToList is a non-deferred query operator, which is the magic that fixes the issue.

If you want the source code for this app, download it here. Be sure to change the file extension from .DOC to .ZIP and then decompress the file.


Good old fashion image animations in WPF

April 23, 2008

As I tried in vain to fall asleep at a reasonable hour tonight, it dawned on me that something is missing from the standard WPF literature. Most of the animation examples show off the awesome built-in support for animations, which means changing a property’s value over time. What I felt was missing is an example of how to create an animation by showing a sequence of images in rapid succession.  Ya know, like Mickey Mouse.  So I got out of bed and made one!

I opened SnagIt, created 37 separate images, saved each one with a name like “001.png”, and then dropped them all into a new project in Visual Studio. All of the image files are copied to the project’s output directory, instead of saving them as resources in the assembly. After assigning the Window’s Content an Image element in XAML, I wrote the following code:

I just love using LINQ!  It makes data processing so much easier.  If you haven’t already done so, I highly recommend you read Joseph Rattz’s “Pro LINQ - Language Integrated Query in C# 2008“.

When I run the app, it looks like this:

If you want the source code, you can download it here. Be sure to change the file extension from .DOC to .ZIP and then decompress the file.