public DelegateCommand CommandOrderBy { get { return new DelegateCommand(Delegated_CommandOrderBy); } }
private void Delegated_CommandOrderBy(object obj)
{
throw new NotImplementedException();
}
public partial class MyListView : ListView
{
GridViewColumnHeader _lastHeaderClicked = null;
public MyListView()
{
InitializeComponent();
}
private void ListViewColumnHeaderClick(object sender, RoutedEventArgs e)
{
GridViewColumnHeader headerClicked = e.OriginalSource as GridViewColumnHeader;
if (headerClicked == null)
return;
if (headerClicked.Role == GridViewColumnHeaderRole.Padding)
return;
var sortingColumn = (headerClicked.Column.DisplayMemberBinding as Binding)?.Path?.Path;
if (sortingColumn == null)
return;
var direction = ApplySort(Items, sortingColumn);
if (direction == ListSortDirection.Ascending)
{
headerClicked.Column.HeaderTemplate =
Resources["HeaderTemplateArrowUp"] as DataTemplate;
}
else
{
headerClicked.Column.HeaderTemplate =
Resources["HeaderTemplateArrowDown"] as DataTemplate;
}
// Remove arrow from previously sorted header
if (_lastHeaderClicked != null && _lastHeaderClicked != headerClicked)
{
_lastHeaderClicked.Column.HeaderTemplate =
Resources["HeaderTemplateDefault"] as DataTemplate;
}
_lastHeaderClicked = headerClicked;
}
public static ListSortDirection ApplySort(ICollectionView view, string propertyName)
{
ListSortDirection direction = ListSortDirection.Ascending;
if (view.SortDescriptions.Count > 0)
{
SortDescription currentSort = view.SortDescriptions[0];
if (currentSort.PropertyName == propertyName)
{
if (currentSort.Direction == ListSortDirection.Ascending)
direction = ListSortDirection.Descending;
else
direction = ListSortDirection.Ascending;
}
view.SortDescriptions.Clear();
}
if (!string.IsNullOrEmpty(propertyName))
{
view.SortDescriptions.Add(new SortDescription(propertyName, direction));
}
return direction;
}
}
101
试试这个:
using System.ComponentModel;
youtItemsControl.Items.SortDescriptions.Add(new SortDescription("yourFavoritePropertyFromItem",ListSortDirection.Ascending);
8 回答
这一切都取决于,如果你使用WPF工具包中的DataGrid,那么就有一个内置的排序,甚至是一个非常有用的多列排序 . 在这里查看更多:
Vincent Sibals Blog
或者,如果您使用的是不支持排序的其他控件,我建议使用以下方法:
Li Gao's Custom Sorting
其次是:
Li Gao's Faster Sorting
我写了一组附加属性来自动排序
GridView
,你可以查看here . 它不处理向上/向下箭头,但可以轻松添加 .MSDN has an easy way to perform sorting on columns带上/下字形 . 该示例不是解释如何使用字形的数据模板 . 以下是我使用ListView的方法 . 这适用于.Net 4 .
在ListView中,您必须指定一个事件处理程序,以便在GridViewColumnHeader上单击时触发 . 我的ListView看起来像这样:
在您的代码中,设置代码来处理排序:
然后在您的XAML中,您需要添加在排序方法中指定的两个DataTemplates:
使用
DockPanel
并将LastChildFill
设置为true将使 Headers 保持在 Headers 的右侧,并让标签填充剩余的空格 . 我将DockPanel
宽度绑定到GridViewColumnHeader
的ActualWidth
因为我的列没有宽度,这使得它们可以自动调整内容 . 不过,我确实在列上设置了MinWidth
,因此字形不会掩盖列 Headers .TextBlock Text
设置为空绑定,显示 Headers 中指定的列名称 .我使用MVVM,所以我创建了一些我自己的附加属性,使用Thomas作为参考 . 当您单击 Headers 时,它会在一列上进行排序,在升序和降序之间切换 . 它从一开始就使用第一列进行排序 . 它显示了Win7 / 8风格的字形 .
通常,您所要做的就是将main属性设置为true(但您必须显式声明GridViewColumnHeaders):
如果要对与显示不同的属性进行排序,则必须声明:
这是附加属性的代码,我喜欢懒惰并将它们放在提供的App.xaml.cs中:
我修改了微软的方式,我在其中覆盖
ListView
控件来制作SortableListView
:行
((Binding)clickedHeader.Column.DisplayMemberBinding).Path.Path
位处理列名与其绑定路径不同的情况,Microsoft方法不这样做 .我想拦截
GridViewColumnHeader.Click
事件,以便我找不到办法 . 因此,我在XAML中为每个SortableListView
添加以下内容:然后在任何包含任意数量的
SortableListView
的Window
上,只需添加以下代码:其中
Controls
只是您在其中创建SortableListView
控件的命名空间的XAML ID .因此,这确实可以防止排序方面的代码重复,您只需要记住如上所述处理事件 .
如果您有listview并将其转换为gridview,则可以通过执行此操作轻松地使gridview列 Headers 可单击 .
然后在代码中设置委托命令 .
我将假设你们都知道如何在这里制作ICommand DelegateCommand . 这允许我保持所有View在ViewModel中单击 .
我只添加了这个,以便有多种方法来完成同样的事情 . 我没有编写用于在 Headers 中添加箭头按钮的代码,但是这将以XAML样式完成,您需要重新设计JanDotNet在其代码中具有的整个标头 .
解决方案总结了现有答案和评论的所有工作部分,包括列 Headers 模板:
View:
Code Behinde:
试试这个: