WPF programmatic data templates

Ever needed to do something programmatically that you do all the time in XAML and been stumped? It would be nice to have a complete list of how to do various things that are simple to do in XAML but a bit non-trivial programmatically. Maybe this exists on the net somewhere, wedged between youtube videos of people injuring themselves and creepy social networking sites, but I haven’t run across it yet. This is the latest stumper I’ve struggled with. How do you programmatically set a data template?

Lets try it out…

Dim _dt As New DataTemplate

Ok, that looks good, type is public (Too often I’m trying to do something, that, it turns out, Microsoft does not want me to do. For my own good, probably), creation no problem. BTW, I’m going to be speaking in VB for a while, as that’s what I’m employed to do currently. If you have trouble trying to decode my accent, I can elaborate.

The most obvious property to set would seem to be…

oh..

not really an obvious property to set…

So I take a look around and see the property VisualTree and that seems a little promising. I get a bit blurry when it comes to some of the distinctions between the logical and visual trees in WPF. Theoritically, it makes a lot of sense and is very straightforward, but at first glance it seems odd that our template only seems to care about visual tree, and not logical. Curiouser and Curiouser.

Interestingly enough it takes a FrameworkElementFactory, which seems logical (as in thought, not as in tree, apparently) to me, as we can’t attach controls multiple times to the WPF heirarchy (at least thats what I’m remembering), so our template obviously needs to furnish a different set of control instances for each time its invoked.

Ok, so lets try making one of those then…

Dim _fef As New FrameworkElementFactory()

So presumably this factory needs to know what to produce….

_fef.Type = GetType(TextBox)

Cool, no problem. This would be fine if we didn’t need to set any values or bindings or whichever, but as we do (doesn’t seem like a DataTemplate would be much good without either of these), we must investigate further.

So much like all of our descendants of DependencyObject and FrameworkElement etc, we seem to be able to set values and bindings on the FrameworkElementFactory. I suspect that these are cached until it actually needs to provide instances of its uninstantiated tree, at which point these bindings and values will be attached. For example we can do.


Dim _binding As New Binding()

_binding.Path = New PropertyPath("SomeTextProperty")

_binding.Source = SomeObject

_fef.SetBinding(TextBox.TextProperty, _binding)

Not so bad after all, and by some internal magic, this binding will wind up on the objects the FrameworkElementFactory furnishes. Note, that the SetBinding we are calling here is NOT the one on FrameworkElement (FrameworkElementFactory does not inherit from this). This further leads me to believe that there is magick going on here.

Probably, when we do a DataTemplate in Xaml, it is instead constructing a tree of these FrameworkElementFactories. Sounds fine to me 😉

On a seperate note, wouldn’t it be nice if we could abuse the VB9 xml literal support, and some Xaml Parsing to do this sort of thing instead? But how to make that gel with some of the things we need to achieve programmatically (which is the whole reason we are doing this in code in the first place). Something to think on……

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: