WPF ListView 在列单击时排序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30787068/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF ListView sorting on column click
提问by user565992
I have a listview for which the items gets added at run time in form of a grid with single/multiple columns. 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 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.
他们应该能够对姓名或号码进行排序。
回答by Liz
This linkis the MSDN way. The main thing is to handle the click on the gridview column header.
这个链接是MSDN方式。主要是处理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).
基本上就是这样。我没有在列标题上添加小方向字形来显示方向。如果您想了解如何执行此操作,可以参考完整教程(请参阅上面的链接)。
回答by Pawcio
It's worth to node that accepted answer assumes the header names are equal to binding paths. Original MSDN takes paths form actual bindings. Here is basically the same code without dozen of redundant if/elses:
对于接受答案的节点来说,假设标头名称等于绑定路径是值得的。原始 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();
}

