简体   繁体   English

列单击时WPF ListView排序

[英]WPF ListView sorting on column click

I have a listview for which the items gets added at run time in form of a grid with single/multiple columns. 我有一个listview,项目在运行时以单个/多个列的网格形式添加。 Now I need to get the sort working. 现在我需要让排序工作。 Once the list view has items in it and they click on the column it should sort it on that column. 列表视图中包含项目并单击列后,应对该列进行排序。

Below is the code for the listview 以下是listview的代码

<ListView Name="lstValue" Margin="0,0,0,10"></ListView>

C# code where it populates the list view: 填充列表视图的C#代码:

 case "Person":
                        dt = GetDataTable(GET_Person)
                        this.lstValue.View = gridview;
                        gridview.Columns.Add(new GridViewColumn { Header = "Number", 
                            DisplayMemberBinding = new Binding("Number") });
                        gridview.Columns.Add(new GridViewColumn { Header = "Name", 
                            DisplayMemberBinding = new Binding("Name") });
                        foreach(DataRow dr in dt.Rows)
                        {
                                                          this.lstValue.Items.Add(new ReportItem { Number = dr["Number"].ToString(),
                                Name = dr["Name"].ToString() });
                        }
                        break;

They should be able to sort on name or number. 他们应该能够对姓名或号码进行排序。

This link is the MSDN way. 链接是MSDN方式。 The main thing is to handle the click on the gridview column header. 主要是处理gridview列标题上的单击。

<ListView x:Name='lv' Height="150" HorizontalAlignment="Center" 
  VerticalAlignment="Center" 
  GridViewColumnHeader.Click="GridViewColumnHeaderClickedHandler"
 >

And in the code: 并在代码中:

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.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(lv.ItemsSource);

  dataView.SortDescriptions.Clear();
  SortDescription sd = new SortDescription(sortBy, direction);
  dataView.SortDescriptions.Add(sd);
  dataView.Refresh();

} }

Basically that's it. 基本上就是这样。 I did not include adding little direction glyphs on the column header to show the direction. 我没有在列标题中添加小方向字形来显示方向。 If you want to see how to do that you can refer to the full tutorial (see link above). 如果您想了解如何操作,可以参考完整的教程(参见上面的链接)。

It's worth to node that accepted answer assumes the header names are equal to binding paths. 节点接受的答案假设标题名称等于绑定路径,这是值得的。 Original MSDN takes paths form actual bindings. 原始MSDN从实际绑定中获取路径。 Here is basically the same code without dozen of redundant if/elses: 这里基本上是相同的代码,没有多余的if / elses:

private GridViewColumnHeader lastHeaderClicked = null;
private ListSortDirection lastDirection = ListSortDirection.Ascending;

private void onHeaderClick(object sender, RoutedEventArgs e) {
    if (!(e.OriginalSource is GridViewColumnHeader ch)) return;
    var dir = ListSortDirection.Ascending;
    if (ch == lastHeaderClicked && lastDirection == ListSortDirection.Ascending)
        dir = ListSortDirection.Descending;
    sort(ch, dir);
    lastHeaderClicked = ch; lastDirection = dir;
}

private void sort(GridViewColumnHeader ch, ListSortDirection dir) {
    var bn = (ch.Column.DisplayMemberBinding as Binding)?.Path.Path;
    bn = bn ?? ch.Column.Header as string;
    var dv = CollectionViewSource.GetDefaultView(accessList.ItemsSource);
    dv.SortDescriptions.Clear();
    var sd = new SortDescription(bn, dir);
    dv.SortDescriptions.Add(sd);
    dv.Refresh();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM