If you need to give users the ability to sort a ListView by clicking on the header, you can use the following method:
First, we will define a style for the header (this is optional, but allows you to specify the alignment of the header). Add the following to the Window.Resources section:
<Style x:Key="myHeaderStyle" TargetType="{x:Type GridViewColumnHeader}">
<Setter Property="HorizontalContentAlignment" Value="Left"/>
</Style>
Now, define the listview (for this example, we will display a list of employees):
<ListView Name="lvwEmployees">
<ListView.View>
<GridView>
<GridViewColumn DisplayMemberBinding="{Binding Path=Name}"
HeaderContainerStyle="{StaticResource myHeaderStyle}" Width="135" >
<GridViewColumnHeader Content="Name" Tag="Name"
Click="GridViewColumnHeader_Click" />
</GridViewColumn>
<GridViewColumn DisplayMemberBinding="{Binding Path=Surname}"
HeaderContainerStyle="{StaticResource myHeaderStyle}" Width="135" >
<GridViewColumnHeader Content="Surname" Tag="Surname"
Click="GridViewColumnHeader_Click" />
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
We will use the Tag property of each GridViewColumnHeader to figure out which one was clicked.
The ListView is bound to a generic list of clsEmployee, defined as follows:
class clsEmployee
{
public clsEmployee(string sName, string sSurname)
{
_Name = sName;
_Surname = sSurname;
}
private string _Name;
private string _Surname;
public string Surname
{
get { return _Surname; }
set { _Surname = value; }
}
public string Name
{
get { return _Name; }
set { _Name = value; }
}
}
Now populate the ListView with dummy data:
Employees = new List<clsEmployee>();
Employees.Add(new clsEmployee("John", "Smith"));
Employees.Add(new clsEmployee("Jenny", "Jones"));
Employees.Add(new clsEmployee("William", "Wilson"));
Employees.Add(new clsEmployee("Susan", "Brown"));
Employees.Add(new clsEmployee("Robert", "Jones"));
Employees.Add(new clsEmployee("David", "Moore"));
Employees.Add(new clsEmployee("Linda", "Taylor"));
lvwEmployees.ItemsSource = Employees;
Now for the click event on the header:
private void GridViewColumnHeader_Click(object sender, RoutedEventArgs e)
{
GridViewColumnHeader ClickedHeader = (GridViewColumnHeader)sender;
Employees.Sort(delegate(clsEmployee e1, clsEmployee e2)
{
if (ClickedHeader.Tag.ToString() == "Name")
{
return e1.Name.CompareTo(e2.Name);
}
else
{
return e1.Surname.CompareTo(e2.Surname);
}
}
);
lvwEmployees.ItemsSource = null;
lvwEmployees.ItemsSource = Employees;
}
This sample only sorts the items ascending. If you swap e1 and e2 in the comparison, the list will be sorted descending.
In this sample, the user will not be able to see the sort direction (usually indicated by an arrow on the header). I will explain how to add this arrow, using an adorner, in another post.