Archive

Archive for May, 2011

CompositeCollection Binding Problem – It’s not part of the Visual Tree

May 31, 2011 5 comments

XAML is fantastic, but occasionally unpredictable which can cause some confusion.

One instance of this is the CompositeCollection tag which is used to build up a collection of values from a number of sources.

An example of this might be as simple as adding a “Please choose…” to the top of a drop down list or more complex scenarios, such as building up a list of products from different suppliers. In most cases, when using MVVM these kind of situations can be handled in the View Model, but even so, it can still be useful to build up lists in the XAML.

One such example I hit recently was creating a context menu for filtering on a data grid. I wanted to filter based on the values in the column, but also add two sorting options at the top of the list. A simplified version of the XAML is shown in Listing 1 below.

<ContextMenu.ItemsSource>
    <CompositeCollection>
        <MenuItem Header="Sort Ascending" />
        <MenuItem Header="Sort Descending" />
        <Separator />
        <CollectionContainer Collection="{Binding Path=FilterOptions}}" />
    </CompositeCollection>
</ContextMenu.ItemsSource>

Listing 1 – Simplified code to show an example usage of CompositeCollection

However if you try to use code such as this you’ll very quickly hit the following binding problem.

Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=FilterOptions; DataItem=null; target element is ‘CollectionContainer’ (HashCode=23627591); target property is ‘Collection’ (type ‘IEnumerable’)

Why? Well it is all down to the fact that the data context of the XAML, specified at the top level that is inherited down through the elements actually goes down the Visual Tree. The killer is that the CompositeCollection, having no visual properties, is not part of the visual tree and therefore does not inherit the data context. The CompositeCollection has no clue what “FilterOptions” is in this example and thus throws a binding error.

Luckily we can easily solve this as all elements have access to the static resources of the XAML so we can easily create a bridging static resource that does the binding that we need and then use that within the composite collection. Listing 2 shows the static resource that we need in this instance.

<Window.Resources>
    <CollectionViewSource x:Key="FilterOptionsBridge" Source="{Binding Path=Filters}" />
</Window.Resources>

Listing 2 – Static resource bridging back to the data context

And finally we can adjust our CollectionContainer to point to the static resource, as in Listing 3.

...
<CollectionContainer Collection="{Binding Source={StaticResource FilterOptionsBridge}}" />
...

Listing 3 – Update to reference the static resource

As a side note, the CollectionViewSource tag needs to bind to an IEnumerable, so if you are binding to a CollectionView or one of the derived classes you’ll need to change the binding to be to the SourceCollection property as shown in Listing 4.

<Window.Resources>
    <CollectionViewSource x:Key="FilterOptionsBridge" Source="{Binding Path=Filters.SourceCollection}" />
</Window.Resources>

Listing 4 – Updated binding to reference the SourceCollection

Advertisements

Code Snippet – proprpc

May 26, 2011 1 comment

Anyone who has played around with WPF or Silverlight for while will have come across the INotifyPropertyChanged interface and the RaisePropertyChanged method.

In an earlier post I highlighted one possible solution, though the use of an extension method, for calling the RaisePropertyChanged method without having to use “magic strings”.

I now use this extensively in my day to day WPF work, however I still sometimes forget to include the RaisePropertyChanged call in the property setter which then takes some time to debug.

In order to avoid this I’ve finally created a code snippet that will insert a field backed property that also calls RaisePropertyChanged.

The snippet is called ‘proprpc‘ so that it is line with the other property snippets of ‘prop‘, ‘propdp‘, ‘propfull‘, etc.

Download links are given below for the .snippet file (including a zipped version) and a Visual Studio Installer file.

Extension Methods on Generics

Sometimes when I’m coding I have the “oh wouldn’t it be nice if this was possible” moments, which turn into great moments when I find to my surprise on occasion that they are.

One such moment recently was realising that I can create extension methods against generic types – something that I had never thought about before. In hindsight of course this is possible, since a specified generic type is an actual static type.

The situation I found myself in recently was whilst coding a bit of filtering code to allow the user to set up dynamic filters. As such I needed a list of comparison operators for which I created an enumerated list as per listing 1 below.

public enum ComparisonOperator
{
    EqualTo,
    NotEqualTo,
    GreaterThan,
    LessThan,
    GreaterThanOrEqualTo,
    LessThanOrEqualTo,
    StartsWith,
    EndsWith,
    Contains,
    IsEmpty,
    IsNotEmpty
}

Since most of the fields that the user could filter on would have similar comparison operators, I found myself adding in the same bunch for each filter type, i.e. a string based field would have ‘StartsWith’, ‘EndsWith’, ‘Contains’, etc.

My “oh wouldn’t it be nice if…” moment was wouldn’t it be nice if I could create an extension method to add in default sets of comparison operators to lists, and I found that I could as per the code in listing 2.

public static class ComparisonOperatorEnum
{
    public static IList AddNumericOperators(this IList comparisonOperatorList)
    {
        return new List<ComparisonOperator>()
            {
                ComparisonOperator.EqualTo,
                ComparisonOperator.IsEmpty,
                ComparisonOperator.IsNotEmpty,
                ComparisonOperator.LessThan,
                ComparisonOperator.LessThanOrEqualTo,
                ComparisonOperator.GreaterThan,
                ComparisonOperator.GreaterThanOrEqualTo,
                ComparisonOperator.NotEqualTo
            };
    }

    public static IList AddStringOperators(this IList comparisonOperatorList)
    {
        return new List<ComparisonOperator>()
            {
                ComparisonOperator.EqualTo,
                ComparisonOperator.NotEqualTo,
                ComparisonOperator.IsEmpty,
                ComparisonOperator.IsNotEmpty,
                ComparisonOperator.Contains,
                ComparisonOperator.StartsWith,
                ComparisonOperator.EndsWith
            };
    }

    public static IList AddReferenceOperators(this IList comparisonOperatorList)
    {
        return new List<ComparisonOperator>()
            {
                ComparisonOperator.EqualTo,
                ComparisonOperator.NotEqualTo,
                ComparisonOperator.IsEmpty,
                ComparisonOperator.IsNotEmpty
            };
    }

    public static IList AddBooleanOperators(this IList comparisonOperatorList)
    {
        return new List<ComparisonOperator>()
            {
                ComparisonOperator.EqualTo,
                ComparisonOperator.NotEqualTo,
                ComparisonOperator.IsEmpty,
                ComparisonOperator.IsNotEmpty
            };
    }
}

This means that my filter definition code is now shorter and clearer, and for those of you who like such things, more fluent.

myFilteredField.ComparisonOperators = new List().AddStringOperators();

It also means that if I add in any additional comparison operators in the future, then I won’t have to hunt down any filtering code and manually add them in.

A happy C# camper.

Categories: C# Tags: , ,