If you need to apply sorting to a ListView, this can be done easily. We just need to handle the GridViewColumnHeader.Click on the ListView. Below you can find the XAML code for doing this:
<window x:class="WpfApplication2.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" title="MainWindow" height="350" width="525">
<grid>
<listview margin="10" name="BusinessListView" gridviewcolumnheader="" click="GridViewColumnHeaderClickedHandler">
<listview.view>
<gridview>
<gridviewcolumn header="Company" width="120" displaymemberbinding="{Binding Company}"></gridviewcolumn>
<gridviewcolumn header="Url" width="200" displaymemberbinding="{Binding Url}"></gridviewcolumn>
<gridviewcolumn header="Phone" width="100" displaymemberbinding="{Binding Phone}"></gridviewcolumn>
</gridview>
</listview.view>
</listview>
</grid>
</window>
And the C# code to handle the click event:
namespace WpfApplication2
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
GridViewColumnHeader _lastHeaderClicked = null;
ListSortDirection _lastDirection = ListSortDirection.Ascending;
public MainWindow()
{
InitializeComponent();
ObservableCollection<business> businesses = new ObservableCollection<business>();
businesses.Add(new Business("Microsoft", "http://www.microsoft.com", "123-421-1231"));
businesses.Add(new Business("SkyXoft", "http://www.skyxoft.com", "123-321-1231"));
businesses.Add(new Business("LicenseSpot", "http://www.licensespot.com", "123-312-3212"));
BusinessListView.ItemsSource = businesses;
}
private void GridViewColumnHeaderClickedHandler(object sender, RoutedEventArgs e)
{
GridViewColumnHeader headerClicked = e.OriginalSource as GridViewColumnHeader;
ListSortDirection direction;
if (headerClicked != null)
{
if (headerClicked.Role != GridViewColumnHeaderRole.Padding)
{
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)
{
ICollectionView dataView = CollectionViewSource.GetDefaultView(BusinessListView.ItemsSource);
dataView.SortDescriptions.Clear();
SortDescription sd = new SortDescription(sortBy, direction);
dataView.SortDescriptions.Add(sd);
dataView.Refresh();
}
}
public class Business
{
public string Company { get; set; }
public string Url { get; set; }
public string Phone { get; set; }
public Business(string company, string url, string phone)
{
this.Company = company;
this.Url = url;
this.Phone = phone;
}
}
}
</business></business>
In the code above we are creating three records in the List and binding it to the ListView. This is the simple and straightforward part.
The difference here is the click event. First we determine what header was clicked and we save that information on the headerClicked variable. Then we checked with a class variable what was the last header clicked. If it is different from the one we just clicked, the the grid is just sorted in ascending mode by default. If it's the same header, then we determine what was the last direction it was clicked and select whether to sort ascending or descending.
At the end we have the Sort method. This will actually get a default view from the ListView ItemsSource. This view has the functionality to sort the rows. We just need create a SortDescription object with the parameters about the header clicked and the direction and call the Refresh method. This will do the trick.