question

CharlesHe-MSFT avatar image
0 Votes"
CharlesHe-MSFT asked ·

How to sort ListView by selected column?

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>


windows-wpf
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

AlexLi-MSFT avatar image
0 Votes"
AlexLi-MSFT answered ·

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>


3501-1544672.gif




Thanks.



1544672.gif (35.4 KiB)
· Share
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

PeterFleischer-3316 avatar image
0 Votes"
PeterFleischer-3316 answered ·

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; }
     }
   }
 }


· Share
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.