Dynamic parameters in XPath WPF bindings.

A graphical depiction of a very simple xml doc...

Image via Wikipedia

Since its been a fair while since I posted anything with technical content, I thought I’d lighten the atmosphere with some hardcore XAML extending 😉

I was asked this question a while back, how to parameterize an XPath query in a binding. Well, it is a bit of problem, you know, ranking right up there with global warming, world peace, North Korean space program crisis etc, and like most lazy developer’s (that’s a good thing btw!) I googled first to see what I could turn up.

There were plenty of scams for solving global warming, but not one for Dynamic XPaths in XAML bindings.

Nothing. Zilch. Nada. Zip. There was one post that made me think that it may well be a bit more difficult that I was expecting.

This post by Karl Hulme almost did what I wanted but not quite. it still wasn’t flexible enough to perform the type of binding I wanted to solve this particular problem, which was, to basically externalise rich tool tip data that was held in an external file, so the client could easily update the data to be shown based on control names on a form. The tool tip had to show not only text, but other rich content that was configured from an XML data source.

So after much head scratching, I came up with what I thought was quite a neat solution. Although it doesn’t solve global warming I think it’s quite a neat solution to the XAML problem. It’s a combination of a Value Converter and a Markup Extension, which allows you to specify XPath bound data in a clean way right in the XAML. The tooltip is then templated using these two classes to display the additional content as well as its original content if any.


In my test case, the binding uses the name of the control that the tool tip added to as the path to the Tool Tips data.

Here’s a piece of code that shows the tool tips markup which will display rich content based on “Button1” in the external data.

<Button x:Name="Button1" Width="120" Height="60" Margin="8">Hover for help!    
<Button.ToolTip>        

<ToolTip Style="{StaticResource toolStyle}"/>    

</Button.ToolTip>

</Button>

Not much to see here, move along! Most of the complex XAML is actually done in the template, from the outside the tooltip looks pretty normal, apart from this tip has no content.

So, what magical incantations do we have to perform in the tool tip style? Well, everywhere we need to drag in some content from the XML data source, we have a control whose source is the said MarkupExtension.

For example we declare one of the labels in the tool tips template like so :

<TextBlock Text="{TipTest:DynamicXPath

Format='/HelpNotes/HelpNote[@Ctrl=&quot{0}&quot]/Guidance',

Source={Binding Path=PlacementTarget,

RelativeSource={RelativeSource AncestorType={x:Type Popup}}} }" 

Foreground="White" />

Note: the whole Format argument is actually one string, unfortunately my blog won’t cope with XAML parameters that are 50,000 characters wide!

Notice that the Source parameter of the markup extension is bound to the Placement target of the control that we know will be hosting the tooltip, solely in order to extract its name. When the DynamicXPath executes, it evaluates the binding to get the control from which to extract the name for use in the markup extensions value converter.

The name of the control is used as part of the XPath which selects a single node where the attribute @Ctrl is equal to the controls name. Neat huh?

Man, you’ve gotta love the flexibility of WPF!

The markup extension then uses the data context of the control as the XML data source.

Although the datasource is provided in the XAML markup for simplicity it can, of course, be any XML document set as the data source somewhere up the controls tree.

The end result is that by specifying the tool tips style we can create dynamic pop ups, based on the controls name. Here’s a shot of the resulting tooltip with an animation playing as part of the rich content.

tipdemo

There’s a second button under the tooltip that has a different ID, and shows different content too. Although both buttons use the same tooltip style, you can of course supply any style for the tooltip. The important parts are the usage of the Markup Extension to extract data from the XML document that are then used as part of the template.

For those of you, like me, too idle to reinvent the wheel the sample application including the DynamicXPath markup extension is available for download

This entry was posted in General. Bookmark the permalink.

Leave a Reply