Using DynamicObject to intercept and marshal property changes

May 22, 2010

One of the most interesting (and potentially dangerous) new features in C# 4.0 is support for the dynamic type.  It allows certain pieces of your code to bypass the normal compile-time type checking features that we have grown to know and love.  You can use a dynamic object however you want to, and the C# compiler will ignore the members you use on it.  At runtime, if the methods/properties/etc. your code tries to use are not actually present on the object, an exception is thrown.  If they do exist, they will be linked to and invoked dynamically.   This technique is called dynamic dispatch.  What you lose in safety, you gain in flexibility.

In addition to the dynamic keyword there is also support in the .NET Framework 4.0 for creating types that support dynamic dispatch. The System.Dynamic.DynamicObject class allows you to specify how an object performs dynamic dispatch.  You can subclass DynamicObject and override some of its methods, such as TrySetMember and TryGetMember, to perform whatever logic you need to link a dynamic property set or get to a backing store.

Sound pretty cool, right?  That’s what I thought when I first heard about this functionality.  Then I thought, “Why would I ever need to use this?”  I didn’t have an answer to that question, until tonight.  It dawned on me, while trying to read something not related to programming (damn OCD!), that this could be leveraged to implement a simple, reusable means of marshaling property changes to the UI thread.

As you probably know, you cannot get or set a visual element’s properties from any thread except the thread on which it was created.  When the UI thread creates an element, that element thereafter has an affinity to the UI thread’s Dispatcher object.  The only property on an element that you can access from another thread is its Dispatcher property.  Once you have a reference to an element’s Dispatcher, you can use it to dispatch method calls that manipulate the element on the UI thread.

If you work on a lot of UI-level components and controls, like I do, you probably find yourself writing a lot of code that works with Dispatchers just to do something simple like get or set an element’s property.  What a pain!  It turns out that this pain can be somewhat eliminated by making use of DynamicObject and the dynamic keyword.  Here’s a contrived example that shows how…

The code snippet above shows how to use my DynamicElement class.  It acts as a proxy to an element, which intercepts all access to an element’s properties.  This interception allows the DynamicElement to make use of the visual element’s Dispatcher, if necessary.  Here is how the interception works for setting a property:

The TryGetMember implementation is similar to the code seen above.

You can download the source code here.  NOTE: Rename the file extension from .DOC to .ZIP and then decompress it.


Using a ViewModel as a value converter

January 8, 2010

A recent post by Josh Twist shows how to support mingling code in XAML for WPF devs.  There have been several examples of putting code into XAML over the years, and they always raise the discussion of whether or not it is a good practice.  I am usually against having code in XAML because it makes it difficult to debug and maintain, but to each his/her own.  Regardless, that post got me thinking…

For a while now I’ve wondered how one might go about making it so that the little bits of code in the XAML might somehow be transplanted into the highly testable, debuggable, lovable world of the ViewModel.  Sure, you could put this type of logic into value converters, but writing a value converter that is only used once seems like a lot of extra work for little benefit.

Just for kicks, I decided to implement a class that would allow you to specify a method on your ViewModel object that contains the code that would otherwise be placed into a value converter, or in XAML.  The result is a markup extension I ever so lazily named BindingEx.  Here’s a simple usage:

Notice the last bit where the ConvertMethod property is set to AdjustTextWidth.  This is how you specify which method on the element’s VM should be invoked when the window’s width changes.  Here’s the VM class:

The TextViewModel object halves the window’s ActualWidth, and that value ends up being the width of the TextBlock.

I’m not sure that anyone should ever use this technique in a real application.  It’s probably a very stupid idea altogether, so I want to avoid any bad karma by stressing the point here:  USE AT YOUR OWN RISK!!

If you want to check out how I implemented BindingEx, click here to download the source code.  Be sure to change the file extension from .DOC to .ZIP and then decompress it.

XAML Tip: DataContext Comment

October 24, 2009

When working on large WPF or Silverlight applications, you can end up with a lot of XAML files.  If you are using the MVVM pattern, many of those XAML files contain a View whose DataContext is expected to be set to a certain type of ViewModel object.  It can sometimes become difficult to remember which Views expects which ViewModel as their DataContext.  One very simple and lightweight way to help you and your team remember a View’s expected DataContext type is to leave an XML comment at the top of the XAML file.  This incredibly simple and obvious technique can be a HUGE timesaver later on down the road!


I highly suggest that you get into the habit of doing this, if you haven’t done so already.  You will thank yourself many times later…

Quick and dirty WPF element tree viewer

September 30, 2009

This morning I decided to build a little WPF dialog window that would show the visual tree of some UI, and provide visual indicators over that UI when you select one of its elements.  This was just a fun exercise.  If you want to have a serious element tree viewer, then be sure to use Snoop instead.  This quick post just shows the result of my morning fun.

Here’s the resulting dialog window in action:


Notice that a ContentPresenter is selected, which contains an image of a ninja.  In the UI being analyzed, you’ll see that the ContentPresenter is decorated with a light green box:


The “Snooper” dialog window contains a TreeView that renders the visual tree of the other UI.  That TreeView is declared as:


It is bound to a hierarchy of VisualElement objects.  VisualElement is a class that I made to represent an element and its child elements.  The important part of that class is seen below:


Notice that when a VisualElement is selected, it puts a SelectionAdorner into the adorner layer of its associated UIElement.  SelectionAdorner is a class I made that just renders a rectangle around some element.  It is seen below:


You can download the demo project here.  NOTE: Be sure to change the file extension from .DOC to .ZIP and then decompress.  WPF is fun!

How to prevent a TabItem from being selected

September 4, 2009

In case you ever need to prevent the user from selecting a tab in a WPF TabControl, here’s one way to do it…


The SelectedContent of the TabControl hasn’t changed at the time that the ItemsSource’s default collection view raises its CurrentChanging event.  If you decide to lock the user into the selected tab, simply set the TabControl’s SelectedIndex back to the index of the SelectedContent.  No fuss, no muss…

Make use of the x:FieldModifier attribute

January 7, 2009

When you give an element a name in XAML, either via the Name property or the x:Name attribute, what you are really doing is supplying a field name for the class into which the XAML is converted.  By default, for whatever reason, those fields are given the “internal” access modifier.  This means that any type within the assembly that contains that class is able to access those elements.  If you appreciate the idea of encapsulation, this is clearly not a good thing!

You can use a little-known attribute called x:FieldModifier to remedy the problem.  By setting x:FieldModifier to “private” the field which references that element will be a private member of the class to which the XAML belongs.  I highly recommend doing this whenever possible, since it promotes a properly designed API for your classes that have a XAML partial.

For example, consider the following XAML:


If you look in the generated file for the Window that contains this XAML, you’ll find the following two fields:

generated code

As you can see, the x:FieldModifier determines which access modifier is applied to the fields that have a name in XAML.  The modifiers do not impact the ability to bind against the fields using an ElementName binding.  Since there is no downside to doing this, there’s no reason not to do it.

Using a ViewModel to Provide Meaningful Validation Error Messages

November 14, 2008

In my MSDN Magazine article about WPF data binding, I briefly mentioned how relying on the binding system to create input validation error messages does not usually lead to a very good user experience.  For example, suppose you bind the Text property of a TextBox to a property of type Int32, and the user types “foo” into the TextBox.  When the binding system tries to convert that string to an int, a FormatException is thrown and subsequently eaten by the data binding pipeline.  The standard technique of showing this validation error, as per most of the WPF documentation and examples, is to set ValidatesOnExceptions to true on the Binding assigned to the TextBox’s Text property.  This approach results in an error message like “Input string was not in a correct format” to be displayed to the user.  Unfortunately, most users have absolutely no idea what that cryptic message means.

The solution to this problem, as with so many others, is to use the Model-View-ViewModel (MVVM) pattern.  Since my article was about data binding, I did not have the liberty to show a better solution to this problem.  During a great conversation with my buddy Karl Shifflett the other night, this topic resurfaced, and I decided that it is time to show a better way.

Let’s take a step back and reassess the problem.  We have a property of a type that can be represented correctly by some, but not all, strings.  WPF does not currently ship with an editor control that knows how to work with this data type correctly (such as having a NumericUpDown control).  When the user types an invalid string into the TextBox that displays a textual representation of the property value, the WPF binding system swallows the parsing exception and, optionally, allows us to display the exception’s error message in the UI.  Most users do not understand what these error messages mean. We need a way to provide meaningful error messages, but to do that it seems that we must somehow crack open that black box known as the WPF data binding pipeline.  Since we cannot do that in a clean and simple way, we cannot take that approach.

The key to this problem is where the input value parsing occurs.  If we let the data binding pipeline parse the input text, we have no way of providing custom error messages, so we must handle the parsing ourselves.  In order to do that, we must expose a property of type String, not Int32, on a ViewModel object, and then bind the TextBox.Text property to that.  If we do that, the binding system has no need to parse the user’s input text for us, because a String is a String, and therefore no type conversion is required.  Once we have taken on the responsibility of parsing the input text, we suddenly have unfettered control over the error messages displayed in the UI.  This allows us to have a user-friendly editing experience, such as the one seen below:


In the demo app, which is available to download at the end of this post, there is a Model class called Person.  It is defined as:

Person class

The Person class implements “business rules” (to use the term loosely) by checking that the Age value is not set to an inappropriate value.  Note, the Age property of the Person class is of type Int32.  In order to make use of the technique I’m proposing, we must create a ViewModel class that wraps a Person instance.  Due to a severe lack of imagination, I named that class PersonViewModel…

PersonViewModel diagram

Within PersonViewModel is another Age property, but this time it is of type String:

PersonViewModel Age property

The TextBox in the Window has its Text property bound to this Age property, not the Age property on the Person object seen previously.  The user can type whatever they want into that TextBox, but the underlying Person object won’t have its Age updated unless they actually type in a valid whole number.  The first layer of defense against invalid input is in PersonViewModel’s implemention of IDataErrorInfo, as seen below:

PersonViewModel implements IDataErrorInfo

The second layer of defense against invalid input is in the Person class, which was listed in its entirety earlier in this post.  That validation logic is only invoked if the input text was able to be parsed to an integer.  As the screenshot below demonstrates, the Person object’s validation logic is still enforced.

Invalid Age message coming from Person object

Download the demo project here.  Note: be sure to change the file extension from .DOC to .ZIP and then decompress it.

Showing an Ellipsis for Clipped Text in a ComboBox

October 11, 2008

If you have a ComboBox with a fixed width, and the selected item is wider than that width, it will be clipped.   That is OK, but it’s nice to let the user know that there is more text than what can be seen.  A common way to do that is by having the text show an ellipsis (…) at the end.  If you do not show the ellipsis, the ComboBox looks something like this:

With the ellipsis, it looks like this:

There are two ways to do this, both of them involve a DataTemplate that contains a TextBlock whose TextTrimming property is set to ‘CharacterEllipsis’.  If you populate the ComboBox by setting its ItemsSource property, you must apply the ellipsis via the ItemTemplate property.  On the other hand, if you populate by adding ComboBoxItems to the Items collection directly, you should create a Style for ComboBoxItem that sets the ContentTemplate to the same DataTemplate you’d use in the other situation.

Here’s an example for setting ItemsSource:

Here’s an example when adding the items directly inline:

Download the demo project here.  Be sure to change the file extension from .DOC to .ZIP and then decompress it.

Binding to (Validation.Errors)[0] without Creating Debug Spew

October 8, 2008

Microsoft’s documentation that shows how to display validation errors for elements says to use a binding like this:

This works, but it causes reams of debug spew to fill the Output window.  Why?  Because is tries to access the first item in the Validation.Errors attached property collection, but if there are no errors, an exception is thrown.  Here’s the type of debug spew that fills the output window:

System.Windows.Data Error: 16 : Cannot get ‘Item[]’ value (type ‘ValidationError’) from ‘(Validation.Errors)’ (type ‘ReadOnlyObservableCollection`1′). BindingExpression:Path=(0).[0].ErrorContent; DataItem=’TextBox’ (Name=’symbolTxt’); target element is ‘TextBox’ (Name=’symbolTxt’); target property is ‘ToolTip’ (type ‘Object’) TargetInvocationException:’System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. —> System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
at System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource)
at System.ThrowHelper.ThrowArgumentOutOfRangeException()
at System.Collections.Generic.List`1.get_Item(Int32 index)
at System.Collections.ObjectModel.Collection`1.get_Item(Int32 index)
at System.Collections.ObjectModel.ReadOnlyCollection`1.get_Item(Int32 index)
— End of inner exception stack trace —
at System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
at System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
at MS.Internal.Data.PropertyPathWorker.GetValue(Object item, Int32 level)
at MS.Internal.Data.PropertyPathWorker.RawValue(Int32 k)’

I use the Output window all the time for debugging purposes, so having it fill up with these error messages breaks my workflow.  I decided to find a better way to display error messages, such that the Output window is not clogged with garbage.  Here’s what I came up with:

When you run my demo app, it looks like this:

The trick is to bind a ContentPresenter’s Content to the CurrentItem of Validation.Errors for the target element.   Binding to the CurrentItem means that we’re  binding to the CurrentItem property of the default ICollectionView that wraps the ReadOnlyObservableCollection<ValidationError> returned by the attached Errors property.  When the current item is non-null, that means there is a validation error; when it is null, there are no validation errors.  We can rely on ICollectionView to safely access the validation error, or not return anything if there are no errors.  That is what prevents the debug spew from pouring out.

The DataTemplate declared in the StackPanel’s Resources knows how to render a ValidationError object.  If the ContentPresenter has a null value, the template is not used to render anything.   That template could also render in a tooltip, if you prefer to keep with Microsoft’s example of showing validation error messages in a tooltip.

Download the demo project here.  Be sure to change the file extension from .DOC to .ZIP and then decompress the file.

The Initially Selected Item when Binding to a Grouped ICollectionView

September 18, 2008

I found a bug in WPF today.  That doesn’t happen very often, but today was one of those days.  If you bind a ListBox to an ICollectionView that has one or more PropertyGroupDescriptions in its GroupDescriptions collection, the initially selected item’s IsSelected property is set to true.  This might not sound like a bug, but it turned out to be one of those issues that took an hour of my life away.  This blog post shows the workaround I came up with.

Suppose you have a collection of PersonViewModel instances, where the class is defined as:

Also suppose that you have these resources set up, and they are applied to the ListBox that displays the list of PersonViewModel objects:

The ListBox is declared as:

The UI also has another ListBox that is not bound to a grouped collection view, and also, beneath the ListBoxs, a TextBlock that shows the selected PersonViewModel’s Bio property. When you run the app, it looks like this:

If you select Steve Smith from the left ListBox, the UI updates accordingly:

However, if you then select Dave Brown again from the right ListBox (the one bound to grouped data), watch what happens:

Yikes!!  The left ListBox and Bio area did not update.  Why not?  Because it turns out that the initially selected item in a ListBox bound to a grouped ICollectionView has its IsSelected property set to true, as a local value.  According to rules of WPF, a local value takes precedence over the value provided by a binding.  So, the binding established on the ListBoxItem’s IsSelected property is overwritten by a local value.

Until Microsoft fixes the bug I reported about this we are stuck using a workaround.  Here’s what I came up with, as seen in the window’s code-behind file.

You can download the demo project here.  This application was compiled in Visual Studio 2008 against .NET 3.5 SP1.  You must change the file extension from .DOC to .ZIP and then decompress it.