ListView Sorting


This sample shows how to create a ListView control that uses a GridView to display a list of dates that are defined as DateTime objects. The sample enables sorting of data in ascending or descending order according to the contents of one column.


Key Step 1. Add Sorting method in GridViewColumnHeader.Click event. Consider both last clicked header and last sorting direction, and decide current sorting direction. Sorting itself is very simple, as written in Sort method.


 



ListView x:Name=lv GridViewColumnHeader.Click=GridViewColumnHeaderClickedHandler>


 



GridViewColumnHeader _lastHeaderClicked = null;


        ListSortDirection _lastDirection = ListSortDirection.Ascending;


 


        void GridViewColumnHeaderClickedHandler(object sender, RoutedEventArgs e)


        {


            GridViewColumnHeader headerClicked = e.OriginalSource as GridViewColumnHeader;


            ListSortDirection direction;


 


            if (headerClicked != null)


            {


                if (headerClicked != _lastHeaderClicked)


                {


                    direction = ListSortDirection.Ascending;


                }


                else


                {


                    if (_lastDirection == ListSortDirection.Ascending)


                    {


                        direction = ListSortDirection.Descending;


                    }


                    else


                    {


                        direction = ListSortDirection.Ascending;


                    }


                }


 


                string header = headerClicked.Column.Header as string;


                Sort(header, direction);


 


                _lastHeaderClicked = headerClicked;


                _lastDirection = direction;


               


            }


           


        }


  


        private void Sort(string sortBy, ListSortDirection direction)


        {


            lv.Items.SortDescriptions.Clear();


            SortDescription sd = new SortDescription(sortBy, direction);


            lv.Items.SortDescriptions.Add(sd);


            lv.Items.Refresh();


        }


 


 


Key Step 2(optional). In order to figure out current sorting status, add Template in the Column Header. Change Template along with sorting status, so it should also be added in GridViewColumnHeader.Click event. And in the Template, Use path to draw the arrows.


 



    <DataTemplate x:Key=HeaderTemplateArrowUp>


      <DockPanel>


        <TextBlock HorizontalAlignment=Center Text={Binding}/>


        <Path x:Name=arrow


           StrokeThickness = 1                                     


           Fill            = gray


           Data            = M 5,10 L 15,10 L 10,5 L 5,10/>


     </DockPanel>


    </DataTemplate>


    <DataTemplate x:Key=HeaderTemplateArrowDown>


      <DockPanel>


        <TextBlock HorizontalAlignment=Center Text={Binding }/>


        <Path x:Name=arrow


              StrokeThickness = 1                                  


              Fill            = gray


              Data            = M 5,5 L 10,10 L 15,5 L 5,5/>


      </DockPanel>


    </DataTemplate>


 



  void GridViewColumnHeaderClickedHandler(object sender, RoutedEventArgs e)


        {


           


 


            if (headerClicked != null)


            {


                if (_lastHeaderClicked != null)


                {


                    _lastHeaderClicked.Column.HeaderTemplate = null;


                }


                 


                if (direction == ListSortDirection.Ascending)


                {


                    headerClicked.Column.HeaderTemplate =


                      Resources[“HeaderTemplateArrowUp”] as DataTemplate;


                }


                else


                {


                    headerClicked.Column.HeaderTemplate =


                      Resources[“HeaderTemplateArrowDown”] as DataTemplate;


                }


 


               


            }


        }


 


Key Step 3. Put it all together and you have the following ListView sorting!



This sample is based on the February CTP.


 


Declaimer: This posting is provided “AS IS” with no warranties, and confers no rights.

ListViewSorting.zip

Comments (8)

  1. stevenkhiem says:

    Dear all,

    My scenario is my listView is bind to DataTable

    and I use BindingListCollectionView to filter data. This is my code:

    // Binding data to ListView

    listViewCustomer.DataContext = _orderTransactionDetailBC.OTDataSet.CompanyList;

    BindingListCollectionView view = (BindingListCollectionView)CollectionViewSource.GetDefaultView(_orderTransactionDetailBC.OTDataSet.CompanyList);

    // Make filtering

    view.CustomFilter = "DeleteFlag = 0";

    view.Refresh();

    My problem is when I remove one or more rows in DataTable, listview remove these rows immediately but it still more focus. And then I remove only one row next times, listview remove more rows. I really don’t know why ?

    Please help me.

    Thanks

  2. Radeldudel says:

    I’m missing something: for me, ListView does not offer the property ‘GridViewColumnHeader.Click’.

    I am using Feb CTP, though. Funny.

  3. ATC Avalon Team says:

    Hello, Radeldudel

    GridViewColumnHeader is derived from ButtonBase and it should have click event. Please double-check the version you used and downloade the source code. If it doesn’t work for you, please paste the error info here. We will help you out.

    Thanks.

  4. GreenHorse says:

    Hi, Everything works fine until I change the GridViewColumn Header="Client Name", then I will receive runtime error "System.InvalidOperationException: "Failed to compare two elements in the array."  Is there any trick that will allow the header use mulitple words?

    Thank you.

  5. GreenHorse says:

    Hi, everything works fine until I change the <GridViewColumn Header = "Two Words" …>. And I received runtime error — System.InvalidOperationException: "Failed to compare two elements in the array.".  Is there any alternative way around it.  I check the forum http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=392037&SiteID=1.  But I don’t understand how the converter will help on the content of the header.  Thanks.

  6. ericallenpaul@hotmail.com says:

    I recently downloaded the VS2005 add-ons for WinFX. I have been playing around with Avalon/WFP/WinFX/XAML (What the heck is the real name anyway?) trying to learn how it works. When I try this example it tells me that "GridViewColumnHeader.Click" doesn’t exist.

    I downloaded the samples most of them won’t display properly in VS2005. They seem to compile and run, but the design view reports some sort of error.

    It looks like WinFX is "Released" but there seem to be a lot of issues. Should I wait until another version to begin writing XBAP apps or is it ok to use this in a production environment?

    Thanks,

    Eric

  7. MSDN Archive says:

    The design experience still requires work. We are hoping to have a much better experience when the next version of Visual Studio ships this year.

Skip to main content