Tips and Tricks: Making Value Converters More Accessible in Markup

I recently had the pleasure of presenting some rather advanced WPF concepts (along with some cool tips and tricks) to a group of smart folks. Unfortunately, I ran up against time constraints and was forced to drop the data binding portion of my talk. I’m a little bummed about not being able to show one cool trick that I use a lot, so here it is…

Call me lazy (really, I’m okay with it), but I’ve never been wild about having to declare my value converters as resources before using them. It’s just one extra step:

I often choose to skip the middleman. Instead of using the StaticResource markup extension to look up a converter, I simply derive my value converter, itself, from MarkupExtension. Then I return an instance of it in the ProvideValue() override.

I have to assume there are plenty of others using this approach too. (It’s clever, afterall, but that’s about the extent of the hyperbole I’d grant it.) If you’re not one of them, I simply wanted to put it out there as a potential trick for your arsenal.

Below is a super simple example of a dummy converter (typically used to debug bindings) that does this:

Do you mean for specifying the ConverterParameter or for supplying a parameter to the constructor of the converter? Both will work, but you’re pretty much stuck with supplying the parameter as a StaticResource (the same as you’d normally do for ConverterParameter) or you could leverage the ObjectReference markup extension I described a while back.

I extended it to save one extra step (because I am lazy too) by making an abstract generic class. This makes it easier to convert my existing ValueConverters to use your technique. Sample code follows:

We tend to use static instance members (like Jacob) and then reference them as “… Converter={x:Static src:TheFooConverter}”.

I’m not sure how much overhead subclassing MarkupExtension is, but the bigger issue for me is that I’m also not sure if I would create a new Converter instance every time ProvideValue() is called — think creating 1000 of these as part of a template. Could put a lot of memory pressure on the app without realizing it, and without necessity — generally you only need one converter instance because it’s reused and does not need to be thread-safe.

I like AlanO’s static approach — best of both worlds.

For parameterizablility (is that even a word?), the MarkupExtension approach gives you more flexibility because you can create the instance inline as opposed to as a resource or as part of the codebehind. But these situations are rare in my experience.

In the example I included above, the converter is a singleton. The markup extension only creates the converter the first time ProvideValue is called and thereafter returns the same instance. Like you say, this works for most converters.

I, too, like AlanO’s example, which takes my static instance approach and puts it in a base class for easy derivation.

I do have some examples of per-instance (nonshared) converters that cache object references for performance reasons. I may post an example of one such converter that I think might help others… I did not include it with this article because it requires carefully explaining the usage scenarios so that the same converter is not inadvertently shared across controls. I’ll see what I can write up. 🙂

I just discovered this trick, felt stupid for not thinking about it earlier, and figured I’d Google to see how many others had thought of it. That’s when I found this page. It’s a little comforting that the publication date wasn’t that long ago ;).

You call this a singleton and say that “the markup extension only creates the converter the first time ProvideValue is called”. That’s not quite accurate. Each time the markup extension is used, a new instance is going to be created, because, well, that’s how markup extensions work. What is true is that only one instance will ever be returned. Use this in a template where it will be used 1000 times, you’ll get 1001 instances constructed, but only 1 of those will not be very shortly garbage collected. It may have some impact on performance, but I doubt you’ll find a scenario where this impact is significant. It won’t have an impact on memory.

There’s a few alternate implementation ideas to consider. First, you might want to consider using a weak reference instead of a strong reference, just so the “singleton” instance isn’t held longer than it needs to be. If your converter is going to be configurable, you have a couple of choices. You can either cache multiple instances based on the values in the markup extension, or just “return this;” from the ProvideValue (knowing what this will mean to memory usage).

The {x:Static foo:MyConverter.Instance} alternative isn’t a bad idea, but only works for non-configurable converters, and is more verbose.

Yes, you are technically correct, Bill. I should have said there is only a single converter that is “used” for conversions.

The converter class in this example has no local fields (just methods), so it is very lightweight. Your argument about the class being instantiated repeatedly is valid, but the same thing is true about StaticResource, DynamicResource, etc, and we certainly don’t worry about the perf impacts with these (which are far more prevalent). As such, I’m okay with the overhead.

If extension is already created and it is also converter we can just “return this;”. It can save us unnecessary ifs, allows base class without template and allows provide additional constructor params specific for instance.
BTW: x:Static is also MarkupExtension and will be created every time, but inside it has a lot of code.