【问题标题】:WPF ListView sorting on column clickWPF ListView 在列单击时排序
【发布时间】:2015-08-27 12:27:35
【问题描述】:

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

下面是列表视图的代码

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

他们应该能够按姓名或号码排序。

【问题讨论】:

    标签: c# .net wpf listview


    【解决方案1】:

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

    }

    基本上就是这样。我没有在列标题上添加小方向字形来显示方向。如果您想了解如何操作,可以参考完整教程(请参阅上面的链接)。

    【讨论】:

    • ICollectionView dataView = CollectionViewSource.GetDefaultView(lstValue.ItemsSource); dataView.SortDescriptions.Clear(); -> 当它运行此语句时,我收到错误“对象引用未设置为对象的实例”错误
    • 抱歉,我没有考虑到您没有使用 ItemsSource 属性这一事实。在您的情况下,将“CollectionViewSource ....”内容更改为 lstValue.Items,它应该可以工作。
    • 我正在尝试这个示例,检测到单击列标题,但未对列表视图进行排序。我也没有收到任何错误。有什么建议吗?
    【解决方案2】:

    值得指出的是,接受的答案假定标头名称等于绑定路径。原始 MSDN 采用实际绑定的路径。 这里基本上是相同的代码,没有十几个多余的 if/else:

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

    【讨论】:

      猜你喜欢
      • 2010-11-02
      • 2020-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多