列单击时WPF ListView排序

时间:2015-06-11 17:03:46

标签: c# .net wpf listview

我有一个列表视图,在运行时以具有单列/多列的网格形式添加项目。现在我需要让排序工作。列表视图中包含项目并单击列后,应对该列进行排序。

以下是listview的代码

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

填充列表视图的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;

他们应该能够对姓名或号码进行排序。

2 个答案:

答案 0 :(得分:7)

link是MSDN方式。主要是处理gridview列标题上的点击。

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

在代码中:

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();

}

基本上就是这样。我没有在列标题中添加小方向字形来显示方向。如果你想看看如何做到这一点,你可以参考完整的教程(见上面的链接)。

答案 1 :(得分:0)

值得节点接受的答案是假设标题名称等于绑定路径。原始MSDN采用实际绑定形式的路径。 这基本上是相同的代码,没有很多多余的if / els:

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