2

I have 7 different ListViews.

There is a Sortmethod called SortClick(object sender, RoutedEventArgs e) - when clicking on a GridViewColumnHeader, it raises the SortClick Event.

But in this method I must tell, which ListView should be Sorted, b.e

listview2.SortNow();

Now my Question is, how can I get the Control (ListView) from the GridViewColumnHeader (sender) or maybe the e, is that even possible?

How the ListView XAML looks like:

<ListView ItemsSource="{Binding MissingTables}" Name="missingTablesListView" HorizontalAlignment="Stretch" VerticalAlignment="Top" Margin="0" MinHeight="540" HorizontalContentAlignment="Stretch">
                    <ListView.Background>
                        <ImageBrush />
                    </ListView.Background>
                    <ListView.View>
                        <GridView>
                            <GridViewColumn DisplayMemberBinding="{Binding TableName}" Width="Auto">
                                <GridViewColumnHeader Click="SortClick" Content="TableName" Tag="TableName" ToolTip="Sortieren" />
                            </GridViewColumn>   
                            <GridViewColumn DisplayMemberBinding="{Binding Beschreibung}" Width="Auto">
                                <GridViewColumnHeader Click="SortClick" Content="Description" Tag="Beschreibung" ToolTip="Sortieren" />
                            </GridViewColumn>
                        </GridView>
                    </ListView.View>
                </ListView>

Here is the SortClick Code:

        /// <summary>
        /// Sortiert (Ascending/Descending)
        /// </summary>
        /// <param name="sender">sender</param>
        /// <param name="e">e</param>
        private void SortClick(object sender, RoutedEventArgs e)
        {       
            //ListView listView = sender as ListView;

            GridViewColumnHeader column = sender as GridViewColumnHeader;
            String field = column.Tag as String;

            if (currentSortColumn != null)
            {
                AdornerLayer.GetAdornerLayer(currentSortColumn).Remove(sorter);
                listView.Items.SortDescriptions.Clear();
            }

            ListSortDirection newDir = ListSortDirection.Ascending;
            if (currentSortColumn == column && sorter.Direction == newDir)
            {
                newDir = ListSortDirection.Descending;
            }

            currentSortColumn = column;
            sorter = new Sorter(currentSortColumn, newDir);
            AdornerLayer.GetAdornerLayer(currentSortColumn).Add(sorter);
            listView.Items.SortDescriptions.Add(new SortDescription(field, newDir));
        }
eMi
  • 5,540
  • 10
  • 60
  • 109

2 Answers2

5

I'm not quite sure what you mean when you say SortClick Event, but i guess you mean the GridViewColumnHeader.Click event with your SortClick handler attached.

If you add the GridViewColumnHeader.Click to the ListViews like this:

<ListView GridViewColumnHeader.Click="SortClick">

you will get the ListView control in the sender argument of your event handler, and the GridViewColumnHeader in e.OriginalSource.

EDIT for clarity. In your SortClick handler, you'll access the control like this:

ListView listView = sender as ListView;
GridViewColumnHeader header = e.OriginalSource as GridViewColumnHeader;
Clemens
  • 123,504
  • 12
  • 155
  • 268
  • yes, but how I get the ListView control from the sender argument? – eMi Feb 06 '12 at 09:53
  • By `ListView listView = sender as ListView;`. – Clemens Feb 06 '12 at 10:04
  • 1
    Can you please post the XAML of (one of) your ListViews, where you attach the click handler? – Clemens Feb 06 '12 at 10:14
  • Add the `SortClick` handler to the `ListView` (as shown in my answer), not to the `GridViewColumnHeader`. – Clemens Feb 06 '12 at 10:19
  • yes, now the listView isn't null, but now I cannot use `sender as GridViewColumnHeader` , I posted my code – eMi Feb 06 '12 at 10:28
  • Read my answer, you'll get the `GridViewColumnHeader` from `e.OriginalSource`. – Clemens Feb 06 '12 at 10:29
  • Please note that GridViewColumnHeader.Click is effectively ButtonBase.Click. That is, any button based controls in the list view will trigger this event, e.g. by clicking on a a toggle button or checkbox. – Ahmad Jul 16 '15 at 12:25
2

I would go with Clemens's solution, but if it's not an option for you, you can also walk up the visual tree to find the ListView:

    static T FindAncestor<T>(DependencyObject obj) where T : DependencyObject
    {
        var tmp = VisualTreeHelper.GetParent(obj);
        while (tmp != null && !(tmp is T))
        {
            tmp = VisualTreeHelper.GetParent(tmp);
        }
        return (T)tmp;
    }

    ...

    var listView = FindAncestor<ListView>(columnHeader);
Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758
  • thx for your solution, but thats to complicated for me :) + 1 for doing this anyway – eMi Feb 06 '12 at 10:32