views:

21

answers:

1

I am trying to implement a ListView with a GridView with sortable columns. To sort the ListView I hook up the Click event for the GridViewColumnHeaders and adding SortDescriptors to the default view source (similar to what is done in MSDN).

Something like this:

<ListView ItemsSource="MY ITEMS SOURCE BINDING">
    <ListView.View>
        <GridView>
            <GridView.Columns>
                <GridViewColumn DisplayMemberBinding="MY DISPLAYMEMBER  BINDING">
                    <GridViewColumnHeader Content="My Header" Click="ColumnHeaderClicked"/>

This all works fine, but I would like to generalize it a bit. To do that I simply derived GridViewColumnHeader and wrote a click-handler. I know there are many sortable list view implementations out there typically deriving from ListView, but I was just wondering if this approach is possible.

Something like this:

<ListView ItemsSource="MY ITEMS SOURCE BINDING">
    <ListView.View>
        <GridView>
            <GridView.Columns>
                <GridViewColumn DisplayMemberBinding="MY DISPLAYMEMBER  BINDING">
                    <local:SortableGridViewColumnHeader Content="My Header"/>

For this to work I need to navigate from the SortableGridViewColumnHeader code to the containing ListView in order to set new SortDescriptors.

I tried navigating up the Parent ladder, but the GridViewColumnHeader is not a visual child of my ListView. Surely I could make a dependency property and bind it to the ListView, but there must be a way to navigate to it instead.

How would I do that in code? (I am not looking for answers on how to sort a WPF ListViews in general, I am wondering if it can be done this way).

EDIT

It turned out that what I needed was this parent searcher in the click-handler of my GridViewColumnHeader derivative.

DependencyObject parent = this;
do
{
    parent = VisualTreeHelper.GetParent(parent);
    if (parent == null) return;
} while (!(parent is ListView));

Now my sorting works like a charm.

+1  A: 

There is a much easier way to do that, using an attached property. Check out this article for details.

<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>
Thomas Levesque
I disagree that this is much easier. The attached property code is far more complex than my simple derived class. An attached property definitely adds a number of benefits, but it is not as simple. My question here was not so much about sorting as how to navigate to the containing ListView. I can see that the code you refer to uses VisualTreeHelper.GetParent. I actually tried this before asking, but failed (that is why I asked). Maybe it's just a bug in my ancestor search.
Holstebroe
"The attached property code is far more complex than my simple derived class": yes, it is. But I'm not saying it's easy to code, I'm saying it's easy to use, which is much more important IMHO ;). Regarding your problem finding the ListView: perhaps that's because the GridViewColumnHeader is not loaded yet when you try to navigate the visual tree... Try to do it in the Loaded event
Thomas Levesque
The GridViewSort code is indeed an inspirational approach, but not easier to use for me than a simple click handler. I would have needed to modify the GridViewSort code to fit my needs since some of my columns should be sorted on multiple properties. Messing around with third part source code can be dangerous.
Holstebroe