Automating null checks with Linq expressions

The problem

Have you ever written code like the following ?

X xx = GetX();
string name = "Default";
if (xx != null && xx.Foo != null && xx.Foo.Bar != null && xx.Foo.Bar.Baz != null)
{
    name = xx.Foo.Bar.Baz.Name;
}

I bet you have ! You just need to get the value of xx.Foo.Bar.Baz.Name, but you have to test every intermediate object to ensure that it’s not null. It can quickly become annoying if the property you need is nested in a deep object graph….

A solution

Linq offers a very interesting feature which can help solve that problem : expressions. C# 3.0 makes it possible to retrieve the abstract syntax tree (AST) of a lambda expression, and perform all kinds of manipulations on it. It is also possible to dynamically generate an AST, compile it to obtain a delegate, and execute it.

How is this related to the problem described above ? Well, Linq makes it possible to analyse the AST for the expression that accesses the xx.Foo.Bar.Baz.Name property, and rewrite that AST to insert null checks where needed. So we’re going to create a NullSafeEval extension method, which takes as a parameter the lambda expression defining how to access a property, and the default value to return if a null object is encountered along the way.

That method will transform the expression xx.Foo.Bar.Baz.Name into that :

    (xx == null)
    ? defaultValue
    : (xx.Foo == null)
      ? defaultValue
      : (xx.Foo.Bar == null)
        ? defaultValue
        : (xx.Foo.Bar.Baz == null)
          ? defaultValue
          : xx.Foo.Bar.Baz.Name;

Here’s the implementation of the NullSafeEval method :

        public static TResult NullSafeEval<TSource, TResult>(this TSource source, Expression<Func<TSource, TResult>> expression, TResult defaultValue)
        {
            var safeExp = Expression.Lambda<Func<TSource, TResult>>(
                NullSafeEvalWrapper(expression.Body, Expression.Constant(defaultValue)),
                expression.Parameters[0]);

            var safeDelegate = safeExp.Compile();
            return safeDelegate(source);
        }

        private static Expression NullSafeEvalWrapper(Expression expr, Expression defaultValue)
        {
            Expression obj;
            Expression safe = expr;

            while (!IsNullSafe(expr, out obj))
            {
                var isNull = Expression.Equal(obj, Expression.Constant(null));

                safe =
                    Expression.Condition
                    (
                        isNull,
                        defaultValue,
                        safe
                    );

                expr = obj;
            }
            return safe;
        }

        private static bool IsNullSafe(Expression expr, out Expression nullableObject)
        {
            nullableObject = null;

            if (expr is MemberExpression || expr is MethodCallExpression)
            {
                Expression obj;
                MemberExpression memberExpr = expr as MemberExpression;
                MethodCallExpression callExpr = expr as MethodCallExpression;

                if (memberExpr != null)
                {
                    // Static fields don't require an instance
                    FieldInfo field = memberExpr.Member as FieldInfo;
                    if (field != null && field.IsStatic)
                        return true;

                    // Static properties don't require an instance
                    PropertyInfo property = memberExpr.Member as PropertyInfo;
                    if (property != null)
                    {
                        MethodInfo getter = property.GetGetMethod();
                        if (getter != null && getter.IsStatic)
                            return true;
                    }
                    obj = memberExpr.Expression;
                }
                else
                {
                    // Static methods don't require an instance
                    if (callExpr.Method.IsStatic)
                        return true;

                    obj = callExpr.Object;
                }

                // Value types can't be null
                if (obj.Type.IsValueType)
                    return true;

                // Instance member access or instance method call is not safe
                nullableObject = obj;
                return false;
            }
            return true;
        }

In short, this code walks up the lambda expression tree, and surrounds each property access or instance method call with a conditional expression (condition ? value if true : value if false).

And here’s how we can use this method :

string name = xx.NullSafeEval(x => x.Foo.Bar.Baz.Name, "Default");

Much clearer and concise than our initial code, isn’t it ? 🙂

Note that the proposed implementation handles not only properties, but also method calls, so we could write something like that :

string name = xx.NullSafeEval(x => x.Foo.GetBar(42).Baz.Name, "Default");

Indexers are not handled yet, but they could be added quite easily ; I will leave it to you to do it if you have the use for it 😉

Limitations

Even though that solution can seem very interesting at first sight, please read what follows before you integrate this code into a real world program…

  • First, the proposed code is just a proof of concept, and as such, hasn’t been thoroughly tested, so it’s probably not very reliable.
  • Secondly, keep in mind that dynamic code generation from an expression tree is tough work for the CLR, and will have a big impact on performance. A quick test shows that using the NullSafeEval method is about 10000 times slower than accessing the property directly…

    A possible approach to limit that issue would be to cache the delegates generated for each expression, to avoid regenerating them every time. Unfortunately, as far as I know there is no simple and reliable way to compare two Linq expressions, which makes it much harder to implement such a cache.

  • Last, you might have noticed that intermediate properties and methods are evaluated several times ; not only this is bad for performance, but more importantly, it could have side effects that are hard to predict, depending on how the properties and methods are implemented.

    A possible workaround would be to rewrite the conditional expression as follows :

    Foo foo = null;
    Bar bar = null;
    Baz baz = null;
    var name =
        (x == null)
        ? defaultValue
        : ((foo = x.Foo) == null)
          ? defaultValue
          : ((bar = foo.Bar) == null)
            ? defaultValue
            : ((baz = bar.Baz) == null)
              ? defaultValue
              : baz.Name;
    

    Unfortunately, this is not possible in .NET 3.5 : that version only supports simple expressions, so it’s not possible to declare variables, assign values to them, or write several distinct instructions. However, in .NET 4.0, support for Linq expressions has been largely improved, and makes it possible to generate that kind of code. I’m currently trying to improve the NullSafeEval method to take advantage of the new .NET 4.0 features, but it turns out to be much more difficult than I had anticipated… If I manage to work it out, I’ll let you know and post the code !

To conclude, I wouldn’t recommend using that technique in real programs, at least not in its current state. However, it gives an interesting insight on the possibilities offered by Linq expressions. If you’re new to this, you should know that Linq expressions are used (among other things) :

  • To generate SQL queries in ORMs like Linq to SQL or Entity Framework
  • To build complex predicates dynamically, like in the PredicateBuilder class by Joseph Albahari
  • To implement “static reflection”, which has generated a lot of buzz on technical blogs lately

[VS2010] Binding support in InputBindings

THE feature that was missing from WPF !

Visual Studio 2010 beta 2 has been released last week, and it brings to WPF a long awaited feature : support for bindings in InputBindings.

As a reminder, the issue in previous releases was that the Command property of the InputBinding class wasn’t a DependencyProperty, so it wasn’t possible to bind it. Furthermore, InputBindings didn’t inherit the parent DataContext, which made it difficult to provide alternative implementations…

Until now, in order to bind the Command of a KeyBinding or MouseBinding to a property of the DataContext, we had to resort to clumsy workarounds… I had eventually came up with an acceptable solution, described in this post, but I wasn’t really satisfied with it (it used reflection on private members, and had annoying limitations).

More recently, I found a better solution in the MVVM toolkit : a CommandReference class, inherited from Freezable, allows to put a reference to a ViewModel command in the page or control resources, so that it can be used later with StaticResource. It’s much cleaner than my previous solution, but still not very straightforward…

WPF 4.0 solves that problem once and for all : the InputBinding class now inherits from Freezable, which allows it to inherit the DataContext, and the Command, CommandParameter and CommandTarget properties are now dependency properties. So, at last, we can forget about the clumsy workarounds described above, and go straight to the point :

    <Window.InputBindings>
        <KeyBinding Key="F5"
                    Command="{Binding RefreshCommand}" />
    </Window.InputBindings>

This new feature should make it much easier to develop MVVM applications !

Help 3

Other than that, I would like to say a few words about the new offline help system that comes with Visual Studio 2010, called “Help 3”. It’s quite a big change compared to previous versions… First, it’s not a standalone application anymore, but a locally hosted web application, so you can access the documentation with your favorite web browser. On the whole, it’s better than the previous system… much faster and more responsive than the old Document Explorer included in previous Visual Studio releases.

However, the new system misses the feature that was the most useful to me : the index ! Now there’s only the hierarchical view, and a search textbox. IMHO, the index was the most convenient way of looking up something in the doc, it made it very easy to access a class or member directly, even without knowing its namespace… why on earth did they remove it ? Worse still : the search results don’t show the namespace, only the class or member name. For instance, if you search “button class”, in the results there is no way to see the difference between System.Windows.Forms.Button, System.Windows.Controls.Button and System.Web.UI.WebControls ! You have to click each link and see where it leads… In Document Explorer, the Index Results pane showed this information clearly.

So, eventually I have mixed feelings about this new help system, because I will have to change the way I use the documentation. But except for this annoying detail, I must concede that it’s objectively a big improvement over the old system…

[C# 4.0] Implementing a custom dynamic object

If you’ve been following the news about .NET, you probably know that the upcoming version 4.0 of C# introduces a new dynamic type. This type allows to access members of an object which are not statically known (at compile time). These members will be resolved at runtime, thanks to the DLR (Dynamic Language Runtime). This feature makes it easier to manipulate COM objects, or any object which type is not statically known. You can find more information about the dynamic type on MSDN.

While playing with Visual Studio 2010 beta, I realized this dynamic type enabled very interesting scenarios… It is indeed possible to create your own dynamic objects, with the ability to control the resolution of dynamic members. To do that, you need to implement the IDynamicMetaObjectProvider interface. This interface seems pretty simple at first sight, since it only defines one member: the GetMetaObject method. But it actually gets trickier when you try to implement this method : you have to build a DynamicMetaObject from an Expression, which is far from trivial… I must admit I almost gave up when I saw the complexity of the task.

Fortunately, there is a much easier way to create your own dynamic objects: you just have to inherit from the DynamicObject class, which provides a basic implementation of IDynamicMetaObjectProvider, and override a few methods to achieve the desired behavior.

Here’s a simple example, inspired from the Javascript language. In Javascript, it is possible to dynamically add members (properties or methods) to an existing type, as in the following sample:

var x = new Object();
x.Message = "Hello world !";
x.ShowMessage = function()
{
  alert(this.Message);
};
x.ShowMessage();

This code creates an object, add a Message property to that object by defining its value, and also adds a ShowMessage method to display the message.

In previous versions of C#, it would have been impossible to do such a thing: indeed C# is a statically typed language, which implies that members are resolved at compile time, not at runtime. Since the Object class doesn’t have a Message property or a ShowMessage method, the compiler won’t accept things like x.Message or x.ShowMessage(). This is where the dynamic type comes to the rescue, since it doesn’t resolve the members at compile time…

Now let’s try to create a dynamic object that allows to write a C# code similar to the Javascript code above. To do that, we will store the values of dynamic properties in a Dictionary<string, object>. To make this class work, we need to override the TryGetMember and TrySetMember methods. These methods implement the logic to read or write a member of the dynamic object. To illustrate the idea, let’s have a look at the code, I’ll comment it later:

public class MyDynamicObject : DynamicObject
{
    private Dictionary<string, object> _properties = new Dictionary<string, object>();

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        return _properties.TryGetValue(binder.Name, out result);
    }

    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        _properties[binder.Name] = value;
        return true;
    }
}

Now let’s explain the code above. The TryGetMember tries to find the requested property in the dictionary. Note that the name of the property is exposed as the Name property of the binder parameter. If the property exists, its value is returned in the result output parameter, and the method returns true. Otherwise, the method returns false, which will cause a RuntimeBinderException at the call site. This exception simply means that the dynamic resolution of the property failed.

The TrySetMember method performs the opposite task: it defines the value of a property. If the member doesn’t exist, it is added to the dictionary, so the method always returns true.

The following sample shows how to use this object:

dynamic x = new MyDynamicObject();
x.Message = "Hello world !";
Console.WriteLine(x.Message);

This code compiles and runs fine, and prints “Hello world !” to the console… easy, isn’t it ?

But what about methods ? Well, I could tell you that you need to override the TryInvokeMember method, which is used to handle dynamic method calls… but actually it’s not even necessary ! Our implementation already handles this feature: we just need to assign a delegate to a property of the object. It won’t actually be a real member method, just a property returning a delegate, but since the syntax to call it will be the same as a method call, it will do fine for now. Here’s an example of adding a method to the object:

dynamic x = new MyDynamicObject();
x.Message = "Hello world !";
x.ShowMessage = new Action(
    () =>
    {
        Console.WriteLine(x.Message);
    });
x.ShowMessage();

Eventually, we end up with something very close to the Javascript we were trying to imitate, all with a class of less than 10 lines of code (not counting the braces)…

This class can be quite handy to use as an general purpose object, for instance to group some data together without having to create a specific class. In that aspect, it’s similar to an anonymous type (already existing in C# 3), but with the benefit that it can be used as a method return value, which is not possible with an anonymous type.

Of course there are many more useful things to do with a custom dynamic object… for instance, here’s a simple wrapper for a DataRow, to make it easier to access the fields:

public class DynamicDataRow : DynamicObject
{
    private DataRow _dataRow;

    public DynamicDataRow(DataRow dataRow)
    {
        if (dataRow == null)
            throw new ArgumentNullException("dataRow");
        this._dataRow = dataRow;
    }

    public DataRow DataRow
    {
        get { return _dataRow; }
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        result = null;
        if (_dataRow.Table.Columns.Contains(binder.Name))
        {
            result = _dataRow[binder.Name];
            return true;
        }
        return false;
    }

    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        if (_dataRow.Table.Columns.Contains(binder.Name))
        {
            _dataRow[binder.Name] = value;
            return true;
        }
        return false;
    }
}

Let’s add a helper extension method to get the wrapper for a row:

public static class DynamicDataRowExtensions
{
    public static dynamic AsDynamic(this DataRow dataRow)
    {
        return new DynamicDataRow(dataRow);
    }
}

We can now write things like that:

DataTable table = new DataTable();
table.Columns.Add("FirstName", typeof(string));
table.Columns.Add("LastName", typeof(string));
table.Columns.Add("DateOfBirth", typeof(DateTime));

dynamic row = table.NewRow().AsDynamic();
row.FirstName = "John";
row.LastName = "Doe";
row.DateOfBirth = new DateTime(1981, 9, 12);
table.Rows.Add(row.DataRow);

// Add more rows...
// ...

var bornInThe20thCentury = from r in table.AsEnumerable()
                           let dr = r.AsDynamic()
                           where dr.DateOfBirth.Year > 1900
                           && dr.DateOfBirth.Year <= 2000
                           select new { dr.LastName, dr.FirstName };

foreach (var item in bornInThe20thCentury)
{
    Console.WriteLine("{0} {1}", item.FirstName, item.LastName);
}

Now that you understand the basic principles for creating custom dynamic objects, you can imagine many more useful applications 🙂

Update : Just after posting this article, I stumbled upon the ExpandoObject class, which does exactly the same thing as the MyDynamicObject class above… It seems I reinvented the wheel again ;). Anyway, it’s interesting to see how dynamic objects work internally, if only for learning purposes… For more details about the ExpandoObject class, check out this post on the C# FAQ blog.

[WPF] Markup extensions and templates

Note : This post follows the one about a a markup extension that can update its target, and reuses the same code.

You may have noticed that using a custom markup extension in a template sometimes lead to unexpected results… In this post I’ll explain what the problem is, and how to create a markup extensions that behaves correctly in a template.

The problem

Let’s take the example from the previous post : a markup extension which gives the state of network connectivity, and updates its target when the network is connected or disconnected :

<CheckBox IsChecked="{my:NetworkAvailable}" Content="Network is available" />

Now let’s put the same CheckBox in a ControlTemplate :

<ControlTemplate x:Key="test">
  <CheckBox IsChecked="{my:NetworkAvailable}" Content="Network is available" />
</ControlTemplate>

And let’s create a control which uses this template :

<Control Template="{StaticResource test}" />

If we disconnect from the network, we notice that the CheckBox is not automatically updated by the NetworkAvailableExtension, whereas it was working fine when we used it outside the template…

Explanation and solution

The markup expression is evaluated when it is encountered by the XAML parser : in that case, when the template is parsed. But at this time, the CheckBox control is not created yet, so the ProvideValue method can’t access it… When a markup extension is evaluated inside a template, the TargetObject is actually an instance of System.Windows.SharedDp, an internal WPF class.

For the markup extension to be able to access its target, it has to be evaluated when the template is applied : we need to defer its evaluation until this time. It’s actually pretty simple, we just need to return the markup extension itself from ProvideValue : this way, it will be evaluated again when the actual target control is created.

To check if the extension is evaluated for the template or for a “real” control, we just need to test whether the type of the TargetObject is System.Windows.SharedDp. So the code of the ProvideValue method becomes :

        public sealed override object ProvideValue(IServiceProvider serviceProvider)
        {
            IProvideValueTarget target = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
            if (target != null)
            {
                if (target.TargetObject.GetType().FullName == "System.Windows.SharedDp")
                    return this;
                _targetObject = target.TargetObject;
                _targetProperty = target.TargetProperty;
            }

            return ProvideValueInternal(serviceProvider);
        }

Cool, it’s now fixed, the CheckBox is updated when the network connectivity changes 🙂

Last, but not least

OK, we have a solution that apparently works fine, but let’s not count our chickens before they’re hatched… What if we now want to use our ControlTemplate on several controls ?

<Control Template="{StaticResource test}" />
<Control Template="{StaticResource test}" />

Now let’s run the application and unplug the network cable : the second CheckBox is updated, but the first one is not…

The reason for this is simple : there are two CheckBox controls, but only one instance of NetworkAvailableExtension, shared between all instances of the template. Now, NetworkAvailableExtension can only reference one target object, so only the last one for which ProvideValue has been called is kept…

So we need to keep track of not one target object, but a collection of target objects, which will all be update by the UpdateValue method. Here’s the final code of the UpdatableMarkupExtension base class :

    public abstract class UpdatableMarkupExtension : MarkupExtension
    {
        private List<object> _targetObjects = new List<object>();
        private object _targetProperty;

        protected IEnumerable<object> TargetObjects
        {
            get { return _targetObjects; }
        }

        protected object TargetProperty
        {
            get { return _targetProperty; }
        }

        public sealed override object ProvideValue(IServiceProvider serviceProvider)
        {
            // Retrieve target information
            IProvideValueTarget target = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;

            if (target != null && target.TargetObject != null)
            {
                // In a template the TargetObject is a SharedDp (internal WPF class)
                // In that case, the markup extension itself is returned to be re-evaluated later
                if (target.TargetObject.GetType().FullName == "System.Windows.SharedDp")
                    return this;

                // Save target information for later updates
                _targetObjects.Add(target.TargetObject);
                _targetProperty = target.TargetProperty;
            }

            // Delegate the work to the derived class
            return ProvideValueInternal(serviceProvider);
        }

        protected virtual void UpdateValue(object value)
        {
            if (_targetObjects.Count > 0)
            {
                // Update the target property of each target object
                foreach (var target in _targetObjects)
                {
                    if (_targetProperty is DependencyProperty)
                    {
                        DependencyObject obj = target as DependencyObject;
                        DependencyProperty prop = _targetProperty as DependencyProperty;

                        Action updateAction = () => obj.SetValue(prop, value);

                        // Check whether the target object can be accessed from the
                        // current thread, and use Dispatcher.Invoke if it can't

                        if (obj.CheckAccess())
                            updateAction();
                        else
                            obj.Dispatcher.Invoke(updateAction);
                    }
                    else // _targetProperty is PropertyInfo
                    {
                        PropertyInfo prop = _targetProperty as PropertyInfo;
                        prop.SetValue(target, value, null);
                    }
                }
            }
        }

        protected abstract object ProvideValueInternal(IServiceProvider serviceProvider);
    }

The UpdatableMarkupExtension is now fully functional… until proved otherwise ;). This class makes a good starting point for any markup extension that needs to update its target, without having to worry about the low-level aspects of tracking and updating target objects.

[WPF] Automatically sort a GridView (continued)

A few months ago, I wrote a post where I explained how to automatically sort a GridView when a column header is clicked. I had mentioned a possible improvement : add a sort glyph in the column header to show which column is sorted. In today’s post, I present a new version of the GridViewSort class, which displays the sort glyph.

GridViewSort sample with sort glyph
GridViewSort sample with sort glyph

To achieve this result, I used an Adorner : this is a component which allows to draw over existing UI elements, on an independant rendering layer.

The new version of the GridViewSort class can be used as before, in that case the grid displays default sort glyphs. These default glyphs are not particularly good-looking, so if you have some artistic skills you can provide you own images, as shown in the code below :

        <ListView ItemsSource="{Binding Persons}"
                  IsSynchronizedWithCurrentItem="True"
                  util:GridViewSort.AutoSort="True"
                  util:GridViewSort.SortGlyphAscending="/Images/up.png"
                  util:GridViewSort.SortGlyphDescending="/Images/down.png">

It is also possible to disable the sort glyphs, by setting the ShowSortGlyph attached property to false :

        <ListView ItemsSource="{Binding Persons}"
                  IsSynchronizedWithCurrentItem="True"
                  util:GridViewSort.AutoSort="True"
                  util:GridViewSort.ShowSortGlyph="False">

Note that in the current version, the sort glyph is only displayed when using the automatic sort mode (AutoSort = true). The case of a custom sort using the Command property is not handled yet.

Here is the complete code of the new version of the class :

using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Documents;

namespace Wpf.Util
{
    public class GridViewSort
    {
        #region Public attached properties

        public static ICommand GetCommand(DependencyObject obj)
        {
            return (ICommand)obj.GetValue(CommandProperty);
        }

        public static void SetCommand(DependencyObject obj, ICommand value)
        {
            obj.SetValue(CommandProperty, value);
        }

        // Using a DependencyProperty as the backing store for Command.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty CommandProperty =
            DependencyProperty.RegisterAttached(
                "Command",
                typeof(ICommand),
                typeof(GridViewSort),
                new UIPropertyMetadata(
                    null,
                    (o, e) =>
                    {
                        ItemsControl listView = o as ItemsControl;
                        if (listView != null)
                        {
                            if (!GetAutoSort(listView)) // Don't change click handler if AutoSort enabled
                            {
                                if (e.OldValue != null && e.NewValue == null)
                                {
                                    listView.RemoveHandler(GridViewColumnHeader.ClickEvent, new RoutedEventHandler(ColumnHeader_Click));
                                }
                                if (e.OldValue == null && e.NewValue != null)
                                {
                                    listView.AddHandler(GridViewColumnHeader.ClickEvent, new RoutedEventHandler(ColumnHeader_Click));
                                }
                            }
                        }
                    }
                )
            );

        public static bool GetAutoSort(DependencyObject obj)
        {
            return (bool)obj.GetValue(AutoSortProperty);
        }

        public static void SetAutoSort(DependencyObject obj, bool value)
        {
            obj.SetValue(AutoSortProperty, value);
        }

        // Using a DependencyProperty as the backing store for AutoSort.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty AutoSortProperty =
            DependencyProperty.RegisterAttached(
                "AutoSort",
                typeof(bool),
                typeof(GridViewSort),
                new UIPropertyMetadata(
                    false,
                    (o, e) =>
                    {
                        ListView listView = o as ListView;
                        if (listView != null)
                        {
                            if (GetCommand(listView) == null) // Don't change click handler if a command is set
                            {
                                bool oldValue = (bool)e.OldValue;
                                bool newValue = (bool)e.NewValue;
                                if (oldValue && !newValue)
                                {
                                    listView.RemoveHandler(GridViewColumnHeader.ClickEvent, new RoutedEventHandler(ColumnHeader_Click));
                                }
                                if (!oldValue && newValue)
                                {
                                    listView.AddHandler(GridViewColumnHeader.ClickEvent, new RoutedEventHandler(ColumnHeader_Click));
                                }
                            }
                        }
                    }
                )
            );

        public static string GetPropertyName(DependencyObject obj)
        {
            return (string)obj.GetValue(PropertyNameProperty);
        }

        public static void SetPropertyName(DependencyObject obj, string value)
        {
            obj.SetValue(PropertyNameProperty, value);
        }

        // Using a DependencyProperty as the backing store for PropertyName.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty PropertyNameProperty =
            DependencyProperty.RegisterAttached(
                "PropertyName",
                typeof(string),
                typeof(GridViewSort),
                new UIPropertyMetadata(null)
            );

        public static bool GetShowSortGlyph(DependencyObject obj)
        {
            return (bool)obj.GetValue(ShowSortGlyphProperty);
        }

        public static void SetShowSortGlyph(DependencyObject obj, bool value)
        {
            obj.SetValue(ShowSortGlyphProperty, value);
        }

        // Using a DependencyProperty as the backing store for ShowSortGlyph.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ShowSortGlyphProperty =
            DependencyProperty.RegisterAttached("ShowSortGlyph", typeof(bool), typeof(GridViewSort), new UIPropertyMetadata(true));

        public static ImageSource GetSortGlyphAscending(DependencyObject obj)
        {
            return (ImageSource)obj.GetValue(SortGlyphAscendingProperty);
        }

        public static void SetSortGlyphAscending(DependencyObject obj, ImageSource value)
        {
            obj.SetValue(SortGlyphAscendingProperty, value);
        }

        // Using a DependencyProperty as the backing store for SortGlyphAscending.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty SortGlyphAscendingProperty =
            DependencyProperty.RegisterAttached("SortGlyphAscending", typeof(ImageSource), typeof(GridViewSort), new UIPropertyMetadata(null));

        public static ImageSource GetSortGlyphDescending(DependencyObject obj)
        {
            return (ImageSource)obj.GetValue(SortGlyphDescendingProperty);
        }

        public static void SetSortGlyphDescending(DependencyObject obj, ImageSource value)
        {
            obj.SetValue(SortGlyphDescendingProperty, value);
        }

        // Using a DependencyProperty as the backing store for SortGlyphDescending.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty SortGlyphDescendingProperty =
            DependencyProperty.RegisterAttached("SortGlyphDescending", typeof(ImageSource), typeof(GridViewSort), new UIPropertyMetadata(null));

        #endregion

        #region Private attached properties

        private static GridViewColumnHeader GetSortedColumnHeader(DependencyObject obj)
        {
            return (GridViewColumnHeader)obj.GetValue(SortedColumnHeaderProperty);
        }

        private static void SetSortedColumnHeader(DependencyObject obj, GridViewColumnHeader value)
        {
            obj.SetValue(SortedColumnHeaderProperty, value);
        }

        // Using a DependencyProperty as the backing store for SortedColumn.  This enables animation, styling, binding, etc...
        private static readonly DependencyProperty SortedColumnHeaderProperty =
            DependencyProperty.RegisterAttached("SortedColumnHeader", typeof(GridViewColumnHeader), typeof(GridViewSort), new UIPropertyMetadata(null));

        #endregion

        #region Column header click event handler

        private static void ColumnHeader_Click(object sender, RoutedEventArgs e)
        {
            GridViewColumnHeader headerClicked = e.OriginalSource as GridViewColumnHeader;
            if (headerClicked != null && headerClicked.Column != null)
            {
                string propertyName = GetPropertyName(headerClicked.Column);
                if (!string.IsNullOrEmpty(propertyName))
                {
                    ListView listView = GetAncestor<ListView>(headerClicked);
                    if (listView != null)
                    {
                        ICommand command = GetCommand(listView);
                        if (command != null)
                        {
                            if (command.CanExecute(propertyName))
                            {
                                command.Execute(propertyName);
                            }
                        }
                        else if (GetAutoSort(listView))
                        {
                            ApplySort(listView.Items, propertyName, listView, headerClicked);
                        }
                    }
                }
            }
        }

        #endregion

        #region Helper methods

        public static T GetAncestor<T>(DependencyObject reference) where T : DependencyObject
        {
            DependencyObject parent = VisualTreeHelper.GetParent(reference);
            while (!(parent is T))
            {
                parent = VisualTreeHelper.GetParent(parent);
            }
            if (parent != null)
                return (T)parent;
            else
                return null;
        }

        public static void ApplySort(ICollectionView view, string propertyName, ListView listView, GridViewColumnHeader sortedColumnHeader)
        {
            ListSortDirection direction = ListSortDirection.Ascending;
            if (view.SortDescriptions.Count > 0)
            {
                SortDescription currentSort = view.SortDescriptions[0];
                if (currentSort.PropertyName == propertyName)
                {
                    if (currentSort.Direction == ListSortDirection.Ascending)
                        direction = ListSortDirection.Descending;
                    else
                        direction = ListSortDirection.Ascending;
                }
                view.SortDescriptions.Clear();

                GridViewColumnHeader currentSortedColumnHeader = GetSortedColumnHeader(listView);
                if (currentSortedColumnHeader != null)
                {
                    RemoveSortGlyph(currentSortedColumnHeader);
                }
            }
            if (!string.IsNullOrEmpty(propertyName))
            {
                view.SortDescriptions.Add(new SortDescription(propertyName, direction));
                if (GetShowSortGlyph(listView))
                    AddSortGlyph(
                        sortedColumnHeader,
                        direction,
                        direction == ListSortDirection.Ascending ? GetSortGlyphAscending(listView) : GetSortGlyphDescending(listView));
                SetSortedColumnHeader(listView, sortedColumnHeader);
            }
        }

        private static void AddSortGlyph(GridViewColumnHeader columnHeader, ListSortDirection direction, ImageSource sortGlyph)
        {
            AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(columnHeader);
            adornerLayer.Add(
                new SortGlyphAdorner(
                    columnHeader,
                    direction,
                    sortGlyph
                    ));
        }

        private static void RemoveSortGlyph(GridViewColumnHeader columnHeader)
        {
            AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(columnHeader);
            Adorner[] adorners = adornerLayer.GetAdorners(columnHeader);
            if (adorners != null)
            {
                foreach (Adorner adorner in adorners)
                {
                    if (adorner is SortGlyphAdorner)
                        adornerLayer.Remove(adorner);
                }
            }
        }

        #endregion

        #region SortGlyphAdorner nested class

        private class SortGlyphAdorner : Adorner
        {
            private GridViewColumnHeader _columnHeader;
            private ListSortDirection _direction;
            private ImageSource _sortGlyph;

            public SortGlyphAdorner(GridViewColumnHeader columnHeader, ListSortDirection direction, ImageSource sortGlyph)
                : base(columnHeader)
            {
                _columnHeader = columnHeader;
                _direction = direction;
                _sortGlyph = sortGlyph;
            }

            private Geometry GetDefaultGlyph()
            {
                double x1 = _columnHeader.ActualWidth - 13;
                double x2 = x1 + 10;
                double x3 = x1 + 5;
                double y1 = _columnHeader.ActualHeight / 2 - 3;
                double y2 = y1 + 5;

                if (_direction == ListSortDirection.Ascending)
                {
                    double tmp = y1;
                    y1 = y2;
                    y2 = tmp;
                }

                PathSegmentCollection pathSegmentCollection = new PathSegmentCollection();
                pathSegmentCollection.Add(new LineSegment(new Point(x2, y1), true));
                pathSegmentCollection.Add(new LineSegment(new Point(x3, y2), true));

                PathFigure pathFigure = new PathFigure(
                    new Point(x1, y1),
                    pathSegmentCollection,
                    true);

                PathFigureCollection pathFigureCollection = new PathFigureCollection();
                pathFigureCollection.Add(pathFigure);

                PathGeometry pathGeometry = new PathGeometry(pathFigureCollection);
                return pathGeometry;
            }

            protected override void OnRender(DrawingContext drawingContext)
            {
                base.OnRender(drawingContext);

                if (_sortGlyph != null)
                {
                    double x = _columnHeader.ActualWidth - 13;
                    double y = _columnHeader.ActualHeight / 2 - 5;
                    Rect rect = new Rect(x, y, 10, 10);
                    drawingContext.DrawImage(_sortGlyph, rect);
                }
                else
                {
                    drawingContext.DrawGeometry(Brushes.LightGray, new Pen(Brushes.Gray, 1.0), GetDefaultGlyph());
                }
            }
        }

        #endregion
    }
}

I hope you’ll find that useful 🙂

Update: uploaded example project to demonstrate how to use the code

[WPF] A markup extension that can update its target

If you have read my previous posts on the topic, you know I’m a big fan of custom markup extensions… However, they have a limitation that can be quite annoying : they are only evaluated once. Yet it would be useful to be able to evaluate them again to update the target property, like a binding… It could be useful in various cases, for instance :

  • if the value of the markup extension can change in response to an event
  • if the state of the target object when the markup extension is evaluated doesn’t allow to determine the value yet, and the evaluation needs to be deferred (for instance, if the DataContext of the target object is needed, but is not yet defined when the markup extension is evaluated)

This post explains how to update the target of a markup extension after the initial evaluation.

The ProvideValue method of a markup extension takes a parameter of type IServiceProvider, which provides, among others, a IProvideValueTarget service. This interface exposes two properties, TargetObject and TargetProperty, which allow to retrieve the target object and property of the markup extension. It is then possible, if you retain this information, to update the property after the markup extension has already been evaluated.

To carry out this task, we can create an abstract class UpdatableMarkupExtension, which saves the target object and property, and provides a method to update the value :

    public abstract class UpdatableMarkupExtension : MarkupExtension
    {
        private object _targetObject;
        private object _targetProperty;

        protected object TargetObject
        {
            get { return _targetObject; }
        }

        protected object TargetProperty
        {
            get { return _targetProperty; }
        }

        public sealed override object ProvideValue(IServiceProvider serviceProvider)
        {
            IProvideValueTarget target = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
            if (target != null)
            {
                _targetObject = target.TargetObject;
                _targetProperty = target.TargetProperty;
            }

            return ProvideValueInternal(serviceProvider);
        }

        protected void UpdateValue(object value)
        {
            if (_targetObject != null)
            {
                if (_targetProperty is DependencyProperty)
                {
                    DependencyObject obj = _targetObject as DependencyObject;
                    DependencyProperty prop = _targetProperty as DependencyProperty;

                    Action updateAction = () =>  obj.SetValue(prop, value);

                    // Check whether the target object can be accessed from the
                    // current thread, and use Dispatcher.Invoke if it can't

                    if (obj.CheckAccess())
                        updateAction();
                    else
                        obj.Dispatcher.Invoke(updateAction);
                }
                else // _targetProperty is PropertyInfo
                {
                    PropertyInfo prop = _targetProperty as PropertyInfo;
                    prop.SetValue(_targetObject, value, null);
                }
            }
        }

        protected abstract object ProvideValueInternal(IServiceProvider serviceProvider);
    }

Since it is essential that the target object and property are saved, we mark the ProvideValue method as sealed so that it cannot be overriden, and we add an abstract ProvideValueInternal method so that inheritors can provide their implementation.

The UpdateValue method handles the update of the target property, which can be either a dependency property (DependencyProperty), or a standard CLR property (PropertyInfo). In the case of a DependencyProperty, the target object inherits from DependencyObject, which itself inherits from DispatcherObject : it is therefore necessary to make sure that the object is only accessed from the thread that owns it, using the CheckAccess and Invoke methods.

Here’s a simple example to illustrate how to use this class. Let’s assume we want to create a custom markup extension which indicates whether the network is available. It would be used like that :

<CheckBox IsChecked="{my:NetworkAvailable}" Content="Network is available" />

Obviously, we want the checkbox to be updated when the availability of the network changes (e.g. when the network cable is plugged or unplugged, or when the Wifi network is out of reach). So we need to handle the NetworkChange.NetworkAvailabilityChanged event, and update the IsChecked property accordingly. So the extension will inherit the UpdatableMarkupExtension class to take advantage of the UpdateValue method :

    public class NetworkAvailableExtension : UpdatableMarkupExtension
    {
        public NetworkAvailableExtension()
        {
            NetworkChange.NetworkAvailabilityChanged += new NetworkAvailabilityChangedEventHandler(NetworkChange_NetworkAvailabilityChanged);
        }

        protected override object ProvideValueInternal(IServiceProvider serviceProvider)
        {
            return NetworkInterface.GetIsNetworkAvailable();
        }

        private void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e)
        {
            UpdateValue(e.IsAvailable);
        }
    }

Note that we subscribe to the NetworkAvailabilityChanged event in the class constructor. If we wanted to subscribe to an event of the target object, we would have to do it in the ProvideValueInternal method, so that the target object can be accessed.

I hope this post let you see how simple it is to implement a markup extension that can update its target at a later time. This enables a behavior similar to a binding, but is not limited to dependency properties. An example of where I use this technique is to create a localization framework that allows to switch language “on the fly”, without restarting the application.

Update :
In its current state, this markup extension can’t be used in a template. For an explanation and a solution to that issue, please read this post.

[C#] Parent/child relationship and XML serialization

Today I’d like to present an idea that occurred to me recently. Nothing about WPF this time, this is all about C# class design !

The problem

It’s very common in C# programs to have an object that owns a collection of child items with a reference to their parent. For instance, this is the case for Windows Forms controls, which have a collection of child controls (Controls), and a reference to their parent control (Parent).

This kind of structure is quite easy to implement, it just requires a bit of plumbing to maintain the consistency of the parent/child relationship. However, if you want to serialize the parent object to XML, it can get tricky… Let’s take a simple, purely theoretical example :

    public class Parent
    {
        public Parent()
        {
            this.Children = new List<Child>();
        }

        public string Name { get; set; }

        public List<Child> Children { get; set; }

        public void AddChild(Child child)
        {
            child.ParentObject = this;
            this.Children.Add(child);
        }

        public void RemoveChild(Child child)
        {
            this.Children.Remove(child);
            child.ParentObject = null;
        }
    }
    public class Child
    {
        public string Name { get; set; }

        public Parent ParentObject { get; set; }
    }

Let’s create an instance of Parent with a few children, and try to serialize it to XML :

            Parent p = new Parent { Name = "The parent" };
            p.AddChild(new Child { Name = "First child" });
            p.AddChild(new Child { Name = "Second child" });

            string xml;
            XmlSerializer xs = new XmlSerializer(typeof(Parent));
            using (StringWriter wr = new StringWriter())
            {
                xs.Serialize(wr, p);
                xml = wr.ToString();
            }

            Console.WriteLine(xml);

When we try to serialize the Parent object, an InvalidOperationException occurs, saying that a circular reference was detected : indeed, the parent references the children, which in turn reference the parent, which references the children… and so on. The obvious solution to that issue is to suppress the serialization of the Child.ParentObject property, which can be done easily by using the XmlIgnore attribute. With that change the serialization works fine, but the problem is not solved yet : when we deserialize the object, the ParentObject property of the children is not set, since it wasn’t serialized… the consistency of the parent/child relationship is broken !

A simple and naive solution would be to loop through the Children collection after the deserialization, in order to set the ParentObject manually. But it’s definitely not an elegant approach… and since I really like elegant code, I thought of something else 😉

The solution

The idea I had to solve this problem consists of a specialized generic collection ChildItemCollection<P,T>, and a IChildItem<P> interface that must be implemented by children.

The IChildItem<P> interface just defines a Parent property of type P :

    /// <summary>
    /// Defines the contract for an object that has a parent object
    /// </summary>
    /// <typeparam name="P">Type of the parent object</typeparam>
    public interface IChildItem<P> where P : class
    {
        P Parent { get; set; }
    }

The ChildItemCollection<P,T> class implements IList<T> by delegating the implementation to a List<T> (or to a collection passed to the constructor), and maintains the parent/child relationship :

    /// <summary>
    /// Collection of child items. This collection automatically set the
    /// Parent property of the child items when they are added or removed
    /// </summary>
    /// <typeparam name="P">Type of the parent object</typeparam>
    /// <typeparam name="T">Type of the child items</typeparam>
    public class ChildItemCollection<P, T> : IList<T>
        where P : class
        where T : IChildItem<P>
    {
        private P _parent;
        private IList<T> _collection;

        public ChildItemCollection(P parent)
        {
            this._parent = parent;
            this._collection = new List<T>();
        }

        public ChildItemCollection(P parent, IList<T> collection)
        {
            this._parent = parent;
            this._collection = collection;
        }

        #region IList<T> Members

        public int IndexOf(T item)
        {
            return _collection.IndexOf(item);
        }

        public void Insert(int index, T item)
        {
            if (item != null)
                item.Parent = _parent;
            _collection.Insert(index, item);
        }

        public void RemoveAt(int index)
        {
            T oldItem = _collection[index];
            _collection.RemoveAt(index);
            if (oldItem != null)
                oldItem.Parent = null;
        }

        public T this[int index]
        {
            get
            {
                return _collection[index];
            }
            set
            {
                T oldItem = _collection[index];
                if (value != null)
                    value.Parent = _parent;
                _collection[index] = value;
                if (oldItem != null)
                    oldItem.Parent = null;
            }
        }

        #endregion

        #region ICollection<T> Members

        public void Add(T item)
        {
            if (item != null)
                item.Parent = _parent;
            _collection.Add(item);
        }

        public void Clear()
        {
            foreach (T item in _collection)
            {
                if (item != null)
                    item.Parent = null;
            }
            _collection.Clear();
        }

        public bool Contains(T item)
        {
            return _collection.Contains(item);
        }

        public void CopyTo(T[] array, int arrayIndex)
        {
            _collection.CopyTo(array, arrayIndex);
        }

        public int Count
        {
            get { return _collection.Count; }
        }

        public bool IsReadOnly
        {
            get { return _collection.IsReadOnly; }
        }

        public bool Remove(T item)
        {
            bool b = _collection.Remove(item);
            if (item != null)
                item.Parent = null;
            return b;
        }

        #endregion

        #region IEnumerable<T> Members

        public IEnumerator<T> GetEnumerator()
        {
            return _collection.GetEnumerator();
        }

        #endregion

        #region IEnumerable Members

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return (_collection as System.Collections.IEnumerable).GetEnumerator();
        }

        #endregion
    }

Now let’s see how this class can be used in the case of the above example… First let’s change the Child class so that it implements the IChildItem<Parent> interface :

    public class Child : IChildItem<Parent>
    {
        public string Name { get; set; }

        [XmlIgnore]
        public Parent ParentObject { get; internal set; }

        #region IChildItem<Parent> Members

        Parent IChildItem<Parent>.Parent
        {
            get
            {
                return this.ParentObject;
            }
            set
            {
                this.ParentObject = value;
            }
        }

        #endregion
    }

Note that here the IChildItem<Parent> interface is implemented explicitly : this is a way to “hide” the Parent property, that will only be accessible when manipulating the Child object through a variable of type IChildItem<Parent>. We also define the set accessor of the ParentObject property as internal, so that it can’t be modified from another assembly.

In the Parent class, the List<Child> just has to be replaced by a ChildItemCollection<Parent, Child>. We also remove the AddChild and RemoveChild methods, which are no more necessary since the ChildItemCollection<P,T> takes care of setting the Parent property.

    public class Parent
    {
        public Parent()
        {
            this.Children = new ChildItemCollection<Parent, Child>(this);
        }

        public string Name { get; set; }

        public ChildItemCollection<Parent, Child> Children { get; private set; }
    }

Note that we give the ChildItemCollection<Parent, Child> constructor a reference to the current object : this is how the collection will know what is the parent of its elements.

The code previously used to serialize a Parent now works fine. During the deserialization, the Child.ParentObject property is not assigned when the Child itself is deserialized (since it has the XmlIgnore attribute), but when the Child is added to the Parent.Children collection.

Eventually, we can see that this solution enables us to keep the parent/child relationship when the object graph is serialized to XML, without resorting to unelegant tricks… However, note that the consistency of the relation can still be broken, if the ParentObject is changed by code outside the ChildItemCollection<P,T> class. To prevent that, some logic must be added to the set accessor to maintain the consistency ; I only omitted that part for the sake of clarity and simplicity.

[Windows Forms] Automatically drag and drop controls (DragMove)

Here’s a piece of code I wrote a while ago, I just thought it could be useful for WinForms developers…

In WPF, there is a very handy method to move a window with no borders : Window.DragMove. It can be used like that :

        private void Window_MouseDown(object sender, MouseButtonEventArgs e)
        {
            this.DragMove();
        }

When you call this method, the window is moved with the mouse until the button is released. It could hardly be simpler 😉

Unfortunately, this method only exists in WPF, and a majority of developers are still working with Windows Forms. So I came up with a solution to use a similar technique in Windows Forms, with a few improvements :

  • Usable on any control, not only a window
  • No need to explicitly handle the MouseDown event
  • Form designer integration, using a IExtenderProvider

My solution consists of the following items :

  • a static DragMoveExtensions class which provides extension methods for the Control class (easily convertible to regular static methods for use with C# 2)
  • a DragMoveProvider component, which implements IExtenderProvider to add a new EnableDragMove property to controls

There are several ways to use this solution, pick the one that best suits your needs :

  • The simplest, which requires no coding at all : in design mode, drop a DragMoveProvider on the Form, and set the EnableDragMove property to true on the Form or control
  • DragMoveProvider
    DragMoveProvider
  • The closest to WPF’s DragMove : in the handler of the MouseDown event, call the DragMove extension method on the Form or control to move
  •         private void label2_MouseDown(object sender, MouseEventArgs e)
            {
                label2.DragMove();
            }
    
  • The most flexible : call the EnableDragMove extension method on the Form or control to move (no event handling needed).
  •         private void checkBox1_CheckedChanged(object sender, EventArgs e)
            {
                this.EnableDragMove(checkBox1.Checked);
            }
    

The attached Visual Studio solution contains the WinFormsDragMove library, and a test project to demonstrate the various ways to use this library. A C#2-compatible version of these projects is also included.

Download source

[WPF] Binding to an asynchronous collection

As you may have noticed, it is not possible to modify the contents of an ObservableCollection on a separate thread if a view is bound to this collection : the CollectionView raises a NotSupportedException :

This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread

To illustrate this, let’s take a simple example : a ListBox bound to a collection of strings in the ViewModel :

        private ObservableCollection<string> _strings = new ObservableCollection<string>();
        public ObservableCollection<string> Strings
        {
            get { return _strings; }
            set
            {
                _strings = value;
                OnPropertyChanged("Strings");
            }
        }
    <ListBox ItemsSource="{Binding Strings}"/>

If we add items to this collection out of the main thread, we get the exception mentioned above. A possible solution would be to create a new collection, and assign it to the Strings property when it is filled, but in this case the UI won’t reflect progress : all items will appear in the ListBox at the same time after the collection is filled, instead of appearing as they are added to the collection. It can be annoying in some cases : for instance, if the ListBox is used to display search results, the user expects to see the results as they are found, like in Windows Search.

A simple way to achieve the desired behavior is to inherit ObservableCollection and override OnCollectionChanged and OnPropertyChanged so that the events are raised on the main thread (actually, the thread that created the collection). The AsyncOperation class is perfectly suited for this need : it allows to “post” a method call on the thread that created it. It is used, for instance, in the BackgroundWorker component, and in many asynchronous methods in the framework (PictureBox.LoadAsync, WebClient.DownloadAsync, etc…).

So, here’s the code of an AsyncObservableCollection class, that can be modified from any thread, and still notify the UI when it is modified :

    public class AsyncObservableCollection<T> : ObservableCollection<T>
    {
        private AsyncOperation asyncOp = null;

        public AsyncObservableCollection()
        {
            CreateAsyncOp();
        }

        public AsyncObservableCollection(IEnumerable<T> list)
            : base(list)
        {
            CreateAsyncOp();
        }

        private void CreateAsyncOp()
        {
            // Create the AsyncOperation to post events on the creator thread
            asyncOp = AsyncOperationManager.CreateOperation(null);
        }

        protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
        {
            // Post the CollectionChanged event on the creator thread
            asyncOp.Post(RaiseCollectionChanged, e);
        }

        private void RaiseCollectionChanged(object param)
        {
            // We are in the creator thread, call the base implementation directly
           base.OnCollectionChanged((NotifyCollectionChangedEventArgs)param);
        }

        protected override void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            // Post the PropertyChanged event on the creator thread
            asyncOp.Post(RaisePropertyChanged, e);
        }

        private void RaisePropertyChanged(object param)
        {
            // We are in the creator thread, call the base implementation directly
            base.OnPropertyChanged((PropertyChangedEventArgs)param);
        }
    }

The only constraint when using this class is that instances of the collection must be created on the UI thread, so that events are raised on that thread.

In the previous example, the only thing to change to make the collection modifiable across threads is the instantiation of the collection in the ViewModel :

private ObservableCollection<string> _strings = new AsyncObservableCollection<string>();

The ListBox can now reflect in real-time the changes made on the collection.

Enjoy 😉

Update : I just found a bug in my implementation : in some cases, using Post to raise the event when the collection is modified from the main thread can cause unpredictable behavior. In that case, the event should of course be raised directly on the main thread, after checking that the current SynchronizationContext is the one in which the collection was created. This also made me realize that the AsyncOperation actually doesn’t bring any benefit : we can use the SynchronizationContext directly instead. So here’s the new implementation :

    public class AsyncObservableCollection<T> : ObservableCollection<T>
    {
        private SynchronizationContext _synchronizationContext = SynchronizationContext.Current;

        public AsyncObservableCollection()
        {
        }

        public AsyncObservableCollection(IEnumerable<T> list)
            : base(list)
        {
        }

        protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
        {
            if (SynchronizationContext.Current == _synchronizationContext)
            {
                // Execute the CollectionChanged event on the current thread
                RaiseCollectionChanged(e);
            }
            else
            {
                // Raises the CollectionChanged event on the creator thread
                _synchronizationContext.Send(RaiseCollectionChanged, e);
            }
        }

        private void RaiseCollectionChanged(object param)
        {
            // We are in the creator thread, call the base implementation directly
            base.OnCollectionChanged((NotifyCollectionChangedEventArgs)param);
        }

        protected override void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            if (SynchronizationContext.Current == _synchronizationContext)
            {
                // Execute the PropertyChanged event on the current thread
                RaisePropertyChanged(e);
            }
            else
            {
                // Raises the PropertyChanged event on the creator thread
                _synchronizationContext.Send(RaisePropertyChanged, e);
            }
        }

        private void RaisePropertyChanged(object param)
        {
            // We are in the creator thread, call the base implementation directly
            base.OnPropertyChanged((PropertyChangedEventArgs)param);
        }
    }

Update: changed the code to use Send instead of Post. Using Post caused the event to be raised asynchronously on the UI thread, which could cause a race condition if the collection was modified again before the previous event was handled.

[WPF] Automatically sort a GridView when a column header is clicked

It’s quite simple, in WPF, to present data in a grid, thanks to the GridView class. If you want to sort it, however, it gets a little harder… With the DataGridView in Windows Forms, it was “automagic” : when the user clicked a column header, the grid was automatically sorted. To achieve the same behavior in WPF, you need to get your hands dirty… The method recommended by Microsoft is described in this article ; it is based on the Click event of the GridViewColumnHeader class. In my view, this approach has two major drawbacks :

  • The sorting must be done in code-behind, something we usually want to avoid if the application is designed according to the MVVM pattern. It also makes the code harder to reuse.
  • This method assumes that the text of the column header is also the name of the property to use as the sort criteria, which isn’t always true, far from it… We could use the DisplayMemberBinding of the column, but it’s not always set (for instance if a CellTemplate is defined instead).

After spending a long time trying to find a flexible and elegant approach, I came up with an interesting solution. It consists of a class with a few attached properties that can be set in XAML.

This class can be used as follows :

    <ListView ItemsSource="{Binding Persons}"
          IsSynchronizedWithCurrentItem="True"
          util:GridViewSort.AutoSort="True">
        <ListView.View>
            <GridView>
                <GridView.Columns>
                    <GridViewColumn Header="Name"
                                    DisplayMemberBinding="{Binding Name}"
                                    util:GridViewSort.PropertyName="Name"/>
                    <GridViewColumn Header="First name"
                                    DisplayMemberBinding="{Binding FirstName}"
                                    util:GridViewSort.PropertyName="FirstName"/>
                    <GridViewColumn Header="Date of birth"
                                    DisplayMemberBinding="{Binding DateOfBirth}"
                                    util:GridViewSort.PropertyName="DateOfBirth"/>
                </GridView.Columns>
            </GridView>
        </ListView.View>
    </ListView>

The GridViewSort.AutoSort property enables automatic sorting for the ListView. The GridViewSort.PropertyName property, defined for each column, indicates the property to use as the sort criteria. There is no extra code to write. A click on a column header triggers the sorting on this column ; if the ListView is already sorted on this column, the sort order is reversed.

In case you need to handle the sorting manually, I also added a GridViewSort.Command attached property. When used with the MVVM pattern, this property allows you to bind to a command declared in the ViewModel :

    <ListView ItemsSource="{Binding Persons}"
          IsSynchronizedWithCurrentItem="True"
          util:GridViewSort.Command="{Binding SortCommand}">
    ...

The sort command takes as parameter the name of the property to use as the sort criteria.

Note : if both the Command and AutoSort properties are set, Command has priority. AutoSort is ignored.

Here is the full code of the GridViewSort class :

using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace Wpf.Util
{
    public class GridViewSort
    {
        #region Attached properties

        public static ICommand GetCommand(DependencyObject obj)
        {
            return (ICommand)obj.GetValue(CommandProperty);
        }

        public static void SetCommand(DependencyObject obj, ICommand value)
        {
            obj.SetValue(CommandProperty, value);
        }

        // Using a DependencyProperty as the backing store for Command.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty CommandProperty =
            DependencyProperty.RegisterAttached(
                "Command",
                typeof(ICommand),
                typeof(GridViewSort),
                new UIPropertyMetadata(
                    null,
                    (o, e) =>
                    {
                        ItemsControl listView = o as ItemsControl;
                        if (listView != null)
                        {
                            if (!GetAutoSort(listView)) // Don't change click handler if AutoSort enabled
                            {
                                if (e.OldValue != null && e.NewValue == null)
                                {
                                    listView.RemoveHandler(GridViewColumnHeader.ClickEvent, new RoutedEventHandler(ColumnHeader_Click));
                                }
                                if (e.OldValue == null && e.NewValue != null)
                                {
                                    listView.AddHandler(GridViewColumnHeader.ClickEvent, new RoutedEventHandler(ColumnHeader_Click));
                                }
                            }
                        }
                    }
                )
            );

        public static bool GetAutoSort(DependencyObject obj)
        {
            return (bool)obj.GetValue(AutoSortProperty);
        }

        public static void SetAutoSort(DependencyObject obj, bool value)
        {
            obj.SetValue(AutoSortProperty, value);
        }

        // Using a DependencyProperty as the backing store for AutoSort.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty AutoSortProperty =
            DependencyProperty.RegisterAttached(
                "AutoSort",
                typeof(bool),
                typeof(GridViewSort),
                new UIPropertyMetadata(
                    false,
                    (o, e) =>
                    {
                        ListView listView = o as ListView;
                        if (listView != null)
                        {
                            if (GetCommand(listView) == null) // Don't change click handler if a command is set
                            {
                                bool oldValue = (bool)e.OldValue;
                                bool newValue = (bool)e.NewValue;
                                if (oldValue && !newValue)
                                {
                                    listView.RemoveHandler(GridViewColumnHeader.ClickEvent, new RoutedEventHandler(ColumnHeader_Click));
                                }
                                if (!oldValue && newValue)
                                {
                                    listView.AddHandler(GridViewColumnHeader.ClickEvent, new RoutedEventHandler(ColumnHeader_Click));
                                }
                            }
                        }
                    }
                )
            );

        public static string GetPropertyName(DependencyObject obj)
        {
            return (string)obj.GetValue(PropertyNameProperty);
        }

        public static void SetPropertyName(DependencyObject obj, string value)
        {
            obj.SetValue(PropertyNameProperty, value);
        }

        // Using a DependencyProperty as the backing store for PropertyName.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty PropertyNameProperty =
            DependencyProperty.RegisterAttached(
                "PropertyName",
                typeof(string),
                typeof(GridViewSort),
                new UIPropertyMetadata(null)
            );

        #endregion

        #region Column header click event handler

        private static void ColumnHeader_Click(object sender, RoutedEventArgs e)
        {
            GridViewColumnHeader headerClicked = e.OriginalSource as GridViewColumnHeader;
            if (headerClicked != null)
            {
                string propertyName = GetPropertyName(headerClicked.Column);
                if (!string.IsNullOrEmpty(propertyName))
                {
                    ListView listView = GetAncestor<ListView>(headerClicked);
                    if (listView != null)
                    {
                        ICommand command = GetCommand(listView);
                        if (command != null)
                        {
                            if (command.CanExecute(propertyName))
                            {
                                command.Execute(propertyName);
                            }
                        }
                        else if (GetAutoSort(listView))
                        {
                            ApplySort(listView.Items, propertyName);
                        }
                    }
                }
            }
        }

        #endregion

        #region Helper methods

        public static T GetAncestor<T>(DependencyObject reference) where T : DependencyObject
        {
            DependencyObject parent = VisualTreeHelper.GetParent(reference);
            while (!(parent is T))
            {
                parent = VisualTreeHelper.GetParent(parent);
            }
            if (parent != null)
                return (T)parent;
            else
                return null;
        }

        public static void ApplySort(ICollectionView view, string propertyName)
        {
            ListSortDirection direction = ListSortDirection.Ascending;
            if (view.SortDescriptions.Count > 0)
            {
                SortDescription currentSort = view.SortDescriptions[0];
                if (currentSort.PropertyName == propertyName)
                {
                    if (currentSort.Direction == ListSortDirection.Ascending)
                        direction = ListSortDirection.Descending;
                    else
                        direction = ListSortDirection.Ascending;
                }
                view.SortDescriptions.Clear();
            }
            if (!string.IsNullOrEmpty(propertyName))
            {
                view.SortDescriptions.Add(new SortDescription(propertyName, direction));
            }
        }

        #endregion
    }
}

Of course, this class could probably be improved… for instance, we could add an arrow glyph on the sorted column (maybe by using an Adorner). Maybe I’ll do that someday… meanwhile, please feel free to use it 😉

Update : A new version that displays the sort glyph in the sorted column is now available in this blog post.

css.php