我看到了ICollectionView
与WPF一起介绍,以处理您需要启用排序和过滤的情况。我甚至看到几篇文章对项目进行排序,但我主要担心的是为什么我的方法失败了。让我们看看我的代码:
<ListView ItemsSource="{Binding}" x:Name="lvItems" GridViewColumnHeader.Click="ListView_Click">
<ListView.View>
<GridView AllowsColumnReorder="True">
<GridViewColumn Header="Id" DisplayMemberBinding="{Binding Id}" />
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" />
<GridViewColumn Header="Developer">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Developer}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Salary">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Salary}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
在代码隐藏中,当点击项目时,我这样做:
ICollectionView Source { get; set; }
private void ListView_Click(object sender, RoutedEventArgs e)
{
GridViewColumnHeader currentHeader = e.OriginalSource as GridViewColumnHeader;
if(currentHeader != null && currentHeader.Role != GridViewColumnHeaderRole.Padding)
{
//using (this.Source.DeferRefresh())
//{
SortDescription currentPropertySort = this.Source.SortDescriptions.FirstOrDefault<SortDescription>(item => item.PropertyName.Equals(currentHeader.Column.Header.ToString()));
if (currentPropertySort != null)
{
if (currentPropertySort.Direction == ListSortDirection.Ascending)
currentPropertySort.Direction = ListSortDirection.Descending;
else
currentPropertySort.Direction = ListSortDirection.Ascending;
}
else
this.Source.SortDescriptions.Add(new SortDescription(currentHeader.Column.Header.ToString(), ListSortDirection.Ascending));
//}
this.Source.Refresh();
this.lvItems.DataContext = this.Source;
this.lvItems.UpdateLayout();
}
}
因此,只要单击ListBox
的标题,就需要对项目进行排序。我使用名为Source的属性持有该集合,然后通过调用lvItems.DataContext = this.Source.
使用它但是代码似乎不起作用。
答案 0 :(得分:3)
这是ListView_Click方法的更新版本,有些工作。我不确定你正在寻找什么排序行为,但下面的版本“堆叠”了一组排序描述,使最后点击的列成为“主要排序描述”。我希望这是有道理的,我希望下面的代码有所帮助。 =)
private void ListView_Click(object sender, RoutedEventArgs e)
{
GridViewColumnHeader currentHeader = e.OriginalSource as GridViewColumnHeader;
if(currentHeader != null && currentHeader.Role != GridViewColumnHeaderRole.Padding)
{
if (this.Source.SortDescriptions
.Count((item) => item.PropertyName.Equals(currentHeader.Column.Header.ToString())) > 0)
{
SortDescription currentPropertySort = this.Source
.SortDescriptions
.First<SortDescription>(item => item.PropertyName.Equals(currentHeader.Column.Header.ToString()));
//Toggle sort direction.
ListSortDirection direction =
(currentPropertySort.Direction == ListSortDirection.Ascending)?
ListSortDirection.Descending : ListSortDirection.Ascending;
//Remove existing sort
this.Source.SortDescriptions.Remove(currentPropertySort);
this.Source.SortDescriptions.Insert(0, new SortDescription(currentHeader.Column.Header.ToString(), direction));
}
else
{
this.Source.SortDescriptions.Insert(0, new SortDescription(currentHeader.Column.Header.ToString(), ListSortDirection.Ascending));
}
this.Source.Refresh();
}
}
修改强>
顺便说一句,上面代码中的一个问题是您调用“FirstOrDefault”来查询现有的SortDescription。请参阅,SortDescription是一个结构,它是不可为空的,因此对FirstOrDefault 的调用永远不会为空,并且将始终返回一个实例。因此,上面代码中的“else-statement”永远不会被调用。