转载:
http://www.kecq.com/artic-10322303.html
以前做了一个数据客户端,不过是直接连数据库的,现在认为这种方式不太好,于是改成服务端RESTful API+客户端,数据处理都在服务端。在编写过程中遇到一些问题,因为之前没有采用分页,所以排序就用DataGrid默认的就行,但是现在需要在服务端分页了,就发现了一些问题,记录下来。
在XAML中有一个名为dataGrid1的DataGrid,点击列头排序只需要在上面加上Sorting属性
<DataGrid Grid.Row="2" x:Name="dataGrid1" AutoGenerateColumns="False" IsReadOnly="True" AlternationCount="2" Sorting="dataGrid1_Sorting" >
初始化的时候可以为某一列指定排序
ICollectionView view = CollectionViewSource.GetDefaultView(list);
view.SortDescriptions.Clear(); //先清除所有的排序
SortDescription sd = new SortDescription("列名", ListSortDirection.Descending);
view.SortDescriptions.Add(sd);
也可以在XAML中指定,假设列名是movieName
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=movieName}" SortDirection="Ascending" SortMemberPath="movieName" Header="名称" />
</DataGrid.Columns>
下面来看主要排序方法
private void dataGrid1_Sorting(object sender, DataGridSortingEventArgs e)
e.Handled = true; //可要可不要 没去仔细研究
pager.OrderColumn = e.Column.SortMemberPath;
ICollectionView view = CollectionViewSource.GetDefaultView(dataGrid1.ItemsSource);
pager.Order = "asc"; //默认升序
if (view.SortDescriptions.Count>0)
if(view.SortDescriptions[0].PropertyName== e.Column.SortMemberPath)
if (view.SortDescriptions[0].Direction == System.ComponentModel.ListSortDirection.Ascending)
pager.Order = "desc";
else if (view.SortDescriptions[0].Direction == ListSortDirection.Descending)
pager.Order = "asc";
LoadData();
e.Column.SortMemberPath 为点击列头的列名,问题就在e.Column.SortDirection 这个属性,如果初始化的时候有指定那么第一次点击的时候能获取到,但是再点击这个属性就是null了,没有指定也是null,好了,我在这里为它赋值e.Column.SortDirection=ListSortDirection.Descending 但是下次点击的时候它还是为null 不知为何,网上没有查到。经过好久摸索,用另一个方法来
ICollectionView view = CollectionViewSource.GetDefaultView(dataGrid1.ItemsSource);
可以从view.SortDescriptions 中取得有排序的列,判断它集合大于0并且列名是当前点击的列,如果当前是升序则变为降序同时查询降序的数据,当然最后还得执行清除排序再添加排序
view.SortDescriptions.Clear(); //先清除所有的排序
SortDescription sd = new SortDescription("列名", ListSortDirection.Descending);
view.SortDescriptions.Add(sd);
这样就实现了服务端排序,不知有无更简单的方法。
文中提到:我在这里为它赋值e.Column.SortDirection=ListSortDirection.Descending,。这里实际效果重新绑定数据后会丢失以前的排序。应该在绑定数据后再重新绑定列的排序状态
所以我这里这样处理的,
1、后端记录上次的排序状态 某列名 升序还是降序
2、绑定数据后,再次赋值当前的排序状态。swich记录的当前排序也就是重新绑定数据前的排序,case某列的排序状态,然后gridResult2.Columns[2].SortDirection重新设置此列的排序状态值。这样就能在DataGridSortingEventArgs e e.Column.SortDirection 属性中获取到重新设置的排序值。这样重新赋值,也能显示自带的排序小箭头。不明白的可以联系www.kaishanguai.com或qq369628105
switch (CurrentOrderByEnum)
{
case (OrderByEnum.OrderByNameAsc):
gridResult2.Columns[2].SortDirection = ListSortDirection.Ascending;
break;
case (OrderByEnum.OrderByNameDesc):
gridResult2.Columns[2].SortDirection = ListSortDirection.Descending;
break;
<DataGrid x:Name="gridResult2" SelectionUnit="FullRow" MinHeight="420" EnableRowVirtualization ="False" GridLinesVisibility="None" BorderThickness="0" AlternationCount="2" ItemsSource="{Binding}" CanUserAddRows="False" HorizontalAlignment="Left" VerticalAlignment="Top" AutoGenerateColumns="False" Visibility="Hidden" IsReadOnly="True" SelectionMode="Extended" Sorting="GridResult2_OnSorting" MouseMove="GridResult2_OnMouseMove" MouseLeftButtonDown="GridResult2_OnMouseLeftButtonDown" MouseLeftButtonUp="GridResult2_OnMouseLeftButtonUp" MouseRightButtonUp="ImageGrid_OnMouseRightButtonDown" LoadingRow="GridResult2_OnLoadingRow" KeyDown="DataView_OnKeyDown" PreviewKeyDown="GridResult2_OnPreviewKeyDown">
<!--SelectionChanged="GridResult2_OnSelectionChanged" -->
<!-- This is required to handle CTRL + C when something is selected in the DataGrid -->
<DataGrid.CommandBindings>
<CommandBinding Command="Copy" Executed="CopyCommand" />
</DataGrid.CommandBindings>
<!-- This is required to handle CTRL + C when something is selected in the DataGrid -->
<DataGrid.InputBindings>
<KeyBinding Key="C" Modifiers="Control" Command="Copy" />
</DataGrid.InputBindings>
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.HeaderTemplate>
<DataTemplate>
<CheckBox Name="ChkAll" ToolTip="All" Content="All" IsChecked="False" Unchecked="UnAll_Checked" Checked="All_Checked"></CheckBox>
</DataTemplate>
</DataGridTemplateColumn.HeaderTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox Checked="ItemFile_OnChecked" Unchecked="ItemFile_OnUnchecked" Tag="{Binding FilePath}" HorizontalAlignment="Center" x:Name="itemFile" VerticalAlignment="Center" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image Source="{Binding SnapshotPath}" Height="20" Width="20" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Name" Binding="{Binding FileName}" />
<DataGridTemplateColumn Header="MD5">
<DataGridTemplateColumn.HeaderStyle>
<Style TargetType="DataGridColumnHeader">
<Setter Property="HorizontalContentAlignment" Value="Center"></Setter>
</Style>
</DataGridTemplateColumn.HeaderStyle>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock HorizontalAlignment="Center" Text="{Binding FileMD5}"></TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Modified Date" CanUserSort="True" SortMemberPath="FileModifiedTime">
<DataGridTemplateColumn.HeaderStyle>
<Style TargetType="DataGridColumnHeader">
<Setter Property="HorizontalContentAlignment" Value="Center"></Setter>
</Style>
</DataGridTemplateColumn.HeaderStyle>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock HorizontalAlignment="Center" Text="{Binding FileModifiedTime}"></TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Path" Binding="{Binding FilePathNoName}" />
<DataGridTemplateColumn Header="Classify Type" CanUserSort="True" SortMemberPath="ClassifyType">
<DataGridTemplateColumn.HeaderStyle>
<Style TargetType="DataGridColumnHeader">
<Setter Property="HorizontalContentAlignment" Value="Center"></Setter>
</Style>
</DataGridTemplateColumn.HeaderStyle>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock HorizontalAlignment="Center" Text="{Binding ClassifyType}"></TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Type">
<DataGridTemplateColumn.HeaderStyle>
<Style TargetType="DataGridColumnHeader">
<Setter Property="HorizontalContentAlignment" Value="Center"></Setter>
</Style>
</DataGridTemplateColumn.HeaderStyle>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock HorizontalAlignment="Center" Text="{Binding FileExtension}"></TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Size(KB)" CanUserSort="True" SortMemberPath="FileSize">
<DataGridTemplateColumn.HeaderStyle>
<Style TargetType="DataGridColumnHeader">
<Setter Property="HorizontalContentAlignment" Value="Center"></Setter>
</Style>
</DataGridTemplateColumn.HeaderStyle>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock HorizontalAlignment="Center" Text="{Binding FileSize, StringFormat={}{0:N0}}"></TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
//绑定数据后,重新设置排序状态
gridResult2.ItemsSource = bindDataList;
//设置排序图标
if (IsClickSort)
switch (CurrentOrderByEnum)
case (OrderByEnum.OrderByNameAsc):
gridResult2.Columns[2].SortDirection = ListSortDirection.Ascending ;
break;
case (OrderByEnum.OrderByNameDesc):
gridResult2.Columns[2].SortDirection = ListSortDirection.Descending;
break;
case (OrderByEnum.OrderByModifiedDateAsc):
gridResult2.Columns[4].SortDirection = ListSortDirection.Ascending ;
break;
case (OrderByEnum.OrderByModifiedDateDesc):
gridResult2.Columns[4].SortDirection = ListSortDirection.Descending;
break;
case (OrderByEnum.OrderByClassifyAsc):
gridResult2.Columns[6].SortDirection = ListSortDirection.Ascending;
break;
case (OrderByEnum.OrderByClassifyDesc):
gridResult2.Columns[6].SortDirection = ListSortDirection.Descending ;
break;
case (OrderByEnum.OrderBySizeAsc):
gridResult2.Columns[8].SortDirection = ListSortDirection.Ascending;
break;
case (OrderByEnum.OrderBySizeDesc):
gridResult2.Columns[8].SortDirection = ListSortDirection.Descending;
break;
gridResult2.Columns[4].SortDirection = ListSortDirection.Descending;
//排序事件
private void GridResult2_OnSorting(object sender, DataGridSortingEventArgs e)
ListSortDirection direction = (e.Column.SortDirection != ListSortDirection.Ascending) ?
ListSortDirection.Ascending : ListSortDirection.Descending;
bool sortAscending = direction == ListSortDirection.Ascending;
switch (e.Column.SortMemberPath)
case ("FileName"):
if (sortAscending)
CurrentOrderByEnum = OrderByEnum.OrderByNameAsc;
CurrentOrderByEnum = OrderByEnum.OrderByNameDesc;
break;
case ("FileModifiedTime"):
if (sortAscending)
CurrentOrderByEnum = OrderByEnum.OrderByModifiedDateAsc;
CurrentOrderByEnum = OrderByEnum.OrderByModifiedDateDesc;
break;
case ("ClassifyType"):
if (sortAscending)
CurrentOrderByEnum = OrderByEnum.OrderByClassifyAsc;
CurrentOrderByEnum = OrderByEnum.OrderByClassifyDesc;
break;
case ("FileSize"):
if (sortAscending)
CurrentOrderByEnum = OrderByEnum.OrderBySizeAsc;
CurrentOrderByEnum = OrderByEnum.OrderBySizeDesc;
break;
IsClickSort = true;
Search();