Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,783 questions
This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
Source thread: how to sort list view with different dataTemplate (int, bool, string, ...), answered by Alex Li-MSFT.
I have a ListView control and I want to sort all the items in the list when user click on specific column header, how to achieve it?
Here is my XAML code:
<ListView ItemsSource="{Binding}" x:Name="listViewControl">
<ListView.View>
<GridView AllowsColumnReorder="True">
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=SomeInteger}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=SomeString}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding SomeBool}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Category" Width="120">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding ElementName=mainWindow, Path=StringList}"
SelectedItem="{Binding Path=SomeString}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</ListView>
Hi,
Welcome to our Microsoft Q&A platform!
You can use my demo:
public partial class MainWindow : Window
{
ObservableCollection<MyClass> list = new ObservableCollection<MyClass>();
public MainWindow()
{
InitializeComponent();
list.Add(new MyClass() { SomeBool = false, SomeInteger = 1, SomeString = "3" });
list.Add(new MyClass() { SomeBool = false, SomeInteger = 2, SomeString = "2" });
list.Add(new MyClass() { SomeBool = true, SomeInteger = 3, SomeString = "3" });
this.DataContext = list;
}
private void ListViewControl_Click(object sender, RoutedEventArgs e)
{
if (e.OriginalSource is GridViewColumnHeader)
{
GridViewColumn clickedColumn = (e.OriginalSource as GridViewColumnHeader).Column;
string bindingProperty=null;
if (clickedColumn != null)
{
if (clickedColumn.Header.ToString() == "column1")
{
bindingProperty = "SomeInteger";
}
if (clickedColumn.Header.ToString() == "column2")
{
bindingProperty = "SomeString";
}
if (clickedColumn.Header.ToString() == "column3")
{
bindingProperty = "SomeBool";
}
SortDescriptionCollection sdc = listViewControl.Items.SortDescriptions;
ListSortDirection sortDirection = ListSortDirection.Ascending;
if (sdc.Count > 0)
{
SortDescription sd = sdc[0];
sortDirection = (ListSortDirection)((((int)sd.Direction) + 1) % 2);
sdc.Clear();
}
sdc.Add(new SortDescription(bindingProperty, sortDirection));
}
}
}
}
public class MyClass
{
public int SomeInteger { get; set; }
public string SomeString { get; set; }
public bool SomeBool { get; set; }
}
Xaml:
<Grid>
<ListView ItemsSource="{Binding}" x:Name="listViewControl" GridViewColumnHeader.Click="ListViewControl_Click">
<ListView.View>
<GridView AllowsColumnReorder="True">
<GridViewColumn Header="column1" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=SomeInteger}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="column2">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=SomeString}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="column3">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding SomeBool}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Category" Width="120">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding ElementName=mainWindow, Path=StringList}"
SelectedItem="{Binding Path=SomeString}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
Thanks.
Try another approach.
XAML:
<Window x:Class="WpfApp1.Window97"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="Window97" Height="450" Width="800">
<Window.Resources>
<local:Window97VM x:Key="vm"/>
</Window.Resources>
<Grid DataContext="{StaticResource vm}">
<ListView ItemsSource="{Binding SimpleLayerView}"
IsSynchronizedWithCurrentItem="True">
<ListView.View>
<GridView AllowsColumnReorder="True">
<GridView.ColumnHeaderTemplate>
<DataTemplate>
<Button Content="{Binding}"
Command="{Binding Cmd, Source={StaticResource vm}}"
CommandParameter="{Binding}"/>
</DataTemplate>
</GridView.ColumnHeaderTemplate>
<GridViewColumn Header="LayerOrder">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding LayerOrder}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="SomeInteger">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding SomeInteger}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="SomeBool">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding SomeBool}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>
And ViewModel:
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Data;
using System.Windows.Input;
namespace WpfApp1
{
public class Window97VM
{
public Window97VM()
{
Random rnd = new Random();
ObservableCollection<Data> l = new ObservableCollection<Data>();
for (int i = 0; i < 11; i++)
l.Add(new Data() { LayerOrder = $"Order {i}", SomeBool = rnd.NextDouble() > 0.5, SomeInteger = rnd.Next(1, 100) });
cvs.Source = l;
}
private CollectionViewSource cvs = new CollectionViewSource();
public ICollectionView SimpleLayerView { get => cvs.View; }
public ICommand Cmd { get => new RelayCommand(CmdExec); }
private void CmdExec(Object obj)
{
string bindingProperty = obj.ToString();
ListSortDirection sortDirection = ListSortDirection.Ascending;
if (SimpleLayerView.SortDescriptions.Count > 0 && SimpleLayerView.SortDescriptions[0].Direction == sortDirection)
sortDirection = ListSortDirection.Descending;
SimpleLayerView.SortDescriptions.Clear();
SimpleLayerView.SortDescriptions.Add(new SortDescription(bindingProperty, sortDirection));
}
public class Data
{
public string LayerOrder { get; set; }
public int SomeInteger { get; set; }
public bool SomeBool { get; set; }
}
}
}