Skip to content

Commit 034fa51

Browse files
committed
Add sorting.
1 parent 210fdba commit 034fa51

10 files changed

Lines changed: 118 additions & 43 deletions

DataGridAsyncDemoMVVM/DataGridAsyncDemoMVVM.csproj

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@
7272
<Generator>MSBuild:Compile</Generator>
7373
<SubType>Designer</SubType>
7474
</ApplicationDefinition>
75+
<Compile Include="converters\DataGridSortingEventArgsToMemberPathSortDirection.cs" />
76+
<Compile Include="filtersort\MemberPathSortingDirection.cs" />
7577
<Compile Include="filtersort\MemberPathFilterText.cs" />
7678
<Compile Include="filtersort\DescriptionList.cs" />
7779
<Compile Include="filtersort\FilterDescription.cs" />
@@ -85,7 +87,7 @@
8587
<Compile Include="RemoteOrDbDataItem.cs" />
8688
<Compile Include="RemoteOrDbDataSourceAsyncProxy.cs" />
8789
<Compile Include="RemoteOrDbDataSourceEmulation.cs" />
88-
<Compile Include="converters\TextChangedEventArgsToDatagridHeaderAndText.cs" />
90+
<Compile Include="converters\TextChangedEventArgsToMemberPathAndText.cs" />
8991
<Page Include="MainWindow.xaml">
9092
<Generator>MSBuild:Compile</Generator>
9193
<SubType>Designer</SubType>
Lines changed: 49 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,82 @@
1-
using System;
2-
using System.ComponentModel;
3-
using System.Diagnostics;
1+
using System.ComponentModel;
42
using System.Threading;
53
using System.Threading.Tasks;
64
using System.Windows.Data;
75
using AlphaChiTech.Virtualization;
86
using DataGridAsyncDemoMVVM.filtersort;
97
using GalaSoft.MvvmLight.Command;
8+
using SortDescription = DataGridAsyncDemoMVVM.filtersort.SortDescription;
109

1110
namespace DataGridAsyncDemoMVVM
1211
{
1312
internal class MainViewModel
1413
{
14+
private readonly VirtualizingObservableCollection<RemoteOrDbDataItem>
15+
_myDataVirtualizedAsyncFilterSortObservableCollection;
16+
1517
private readonly RemoteOrDbDataSourceAsyncProxy _myRemoteOrDbDataSourceAsyncProxy;
16-
private VirtualizingObservableCollection<RemoteOrDbDataItem> myDataVirtualizedAsyncFilterSortObservableCollection;
18+
19+
private int _filterWaitingCount;
1720

1821
public MainViewModel()
1922
{
20-
this._myRemoteOrDbDataSourceAsyncProxy = new RemoteOrDbDataSourceAsyncProxy(new RemoteOrDbDataSourceEmulation(100));
21-
this.myDataVirtualizedAsyncFilterSortObservableCollection =
23+
this._myRemoteOrDbDataSourceAsyncProxy =
24+
new RemoteOrDbDataSourceAsyncProxy(new RemoteOrDbDataSourceEmulation(100));
25+
this._myDataVirtualizedAsyncFilterSortObservableCollection =
2226
new VirtualizingObservableCollection<RemoteOrDbDataItem>(
2327
new PaginationManager<RemoteOrDbDataItem>(this._myRemoteOrDbDataSourceAsyncProxy,
2428
pageSize: 10, maxPages: 2));
2529
this.MyDataVirtualizedAsyncFilterSortObservableCollectionCollectionView =
26-
CollectionViewSource.GetDefaultView(myDataVirtualizedAsyncFilterSortObservableCollection);
30+
CollectionViewSource.GetDefaultView(this._myDataVirtualizedAsyncFilterSortObservableCollection);
2731

28-
this.FilterCommand = new RelayCommand<object>(async o => await this.Filter(o as MemberPathFilterText));
32+
this.FilterCommand = new RelayCommand<MemberPathFilterText>(async o => await this.Filter(o));
33+
this.SortCommand = new RelayCommand<MemberPathSortingDirection>(async o => await this.Sort(o));
2934
}
3035

31-
private int _filterWaitingCount = 0;
32-
private async Task Filter(MemberPathFilterText memberPathFilterText)
36+
public ICollectionView MyDataVirtualizedAsyncFilterSortObservableCollectionCollectionView { get; }
37+
38+
public RelayCommand<MemberPathFilterText> FilterCommand { get; }
39+
40+
public RelayCommand<MemberPathSortingDirection> SortCommand { get; }
41+
42+
private async Task Sort(MemberPathSortingDirection memberPathSortingDirection)
3343
{
34-
if (String.IsNullOrWhiteSpace(memberPathFilterText.FilterText))
44+
while (this._filterWaitingCount != 0)
45+
await Task.Delay(500);
46+
var sortDirection = memberPathSortingDirection.SortDirection;
47+
var sortMemberPath = memberPathSortingDirection.MemberPath;
48+
switch (sortDirection)
3549
{
36-
this._myRemoteOrDbDataSourceAsyncProxy.FilterDescriptionList.Remove(memberPathFilterText
37-
.ColumnSortMemberPath);
50+
case null:
51+
this._myRemoteOrDbDataSourceAsyncProxy.SortDescriptionList.Remove(sortMemberPath);
52+
break;
53+
case ListSortDirection.Ascending:
54+
this._myRemoteOrDbDataSourceAsyncProxy.SortDescriptionList.Add(
55+
new SortDescription(sortMemberPath, ListSortDirection.Ascending));
56+
break;
57+
case ListSortDirection.Descending:
58+
this._myRemoteOrDbDataSourceAsyncProxy.SortDescriptionList.Add(
59+
new SortDescription(sortMemberPath, ListSortDirection.Descending));
60+
break;
3861
}
62+
63+
this._myRemoteOrDbDataSourceAsyncProxy.FilterDescriptionList.OnCollectionReset();
64+
this._myDataVirtualizedAsyncFilterSortObservableCollection.Clear();
65+
}
66+
67+
private async Task Filter(MemberPathFilterText memberPathFilterText)
68+
{
69+
if (string.IsNullOrWhiteSpace(memberPathFilterText.FilterText))
70+
this._myRemoteOrDbDataSourceAsyncProxy.FilterDescriptionList.Remove(memberPathFilterText
71+
.MemberPath);
3972
else
40-
{
41-
this._myRemoteOrDbDataSourceAsyncProxy.FilterDescriptionList.Add(new FilterDescription(memberPathFilterText.ColumnSortMemberPath, memberPathFilterText.FilterText));
42-
}
73+
this._myRemoteOrDbDataSourceAsyncProxy.FilterDescriptionList.Add(
74+
new FilterDescription(memberPathFilterText.MemberPath, memberPathFilterText.FilterText));
4375
Interlocked.Increment(ref this._filterWaitingCount);
4476
await Task.Delay(500);
4577
if (Interlocked.Decrement(ref this._filterWaitingCount) != 0) return;
4678
this._myRemoteOrDbDataSourceAsyncProxy.FilterDescriptionList.OnCollectionReset();
47-
this.myDataVirtualizedAsyncFilterSortObservableCollection.Clear();
79+
this._myDataVirtualizedAsyncFilterSortObservableCollection.Clear();
4880
}
49-
50-
public ICollectionView MyDataVirtualizedAsyncFilterSortObservableCollectionCollectionView { get; }
51-
52-
public RelayCommand<object> FilterCommand { get; }
5381
}
5482
}

DataGridAsyncDemoMVVM/MainWindow.xaml

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
Height="350"
1111
DataContext="{StaticResource MainViewModel}">
1212
<Window.Resources>
13-
<converters:TextChangedEventArgsToDatagridHeaderAndText x:Key="TextChangedEventArgsToDatagridHeaderAndText" />
13+
<converters:TextChangedEventArgsToMemberPathAndText x:Key="TextChangedEventArgsToMemberPathAndText" />
14+
<converters:DataGridSortingEventArgsToMemberPathSortDirection
15+
x:Key="DataGridSortingEventArgsToMemberPathSortDirection" />
1416
</Window.Resources>
1517
<Grid>
1618
<Grid.RowDefinitions>
@@ -22,7 +24,14 @@
2224
Grid.Row="1"
2325
CanUserSortColumns="True"
2426
ItemsSource="{Binding MyDataVirtualizedAsyncFilterSortObservableCollectionCollectionView}">
25-
27+
<i:Interaction.Triggers>
28+
<i:EventTrigger EventName="Sorting">
29+
<cmd:EventToCommand
30+
Command="{Binding Mode=OneWay, Path=SortCommand}"
31+
EventArgsConverter="{StaticResource DataGridSortingEventArgsToMemberPathSortDirection}"
32+
PassEventArgsToCommand="True" />
33+
</i:EventTrigger>
34+
</i:Interaction.Triggers>
2635
<DataGrid.ColumnHeaderStyle>
2736
<Style TargetType="DataGridColumnHeader">
2837
<Setter Property="HorizontalAlignment" Value="Stretch" />
@@ -50,8 +59,8 @@
5059
<cmd:EventToCommand
5160
Command="{Binding Mode=OneWay,
5261
Path=DataContext.FilterCommand,
53-
RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
54-
EventArgsConverter="{StaticResource TextChangedEventArgsToDatagridHeaderAndText}"
62+
RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
63+
EventArgsConverter="{StaticResource TextChangedEventArgsToMemberPathAndText}"
5564
PassEventArgsToCommand="True" />
5665
</i:EventTrigger>
5766
</i:Interaction.Triggers>

DataGridAsyncDemoMVVM/MainWindow.xaml.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
#region
22

33
using System;
4-
using System.Diagnostics;
54
using System.Windows;
6-
using System.Windows.Controls;
75
using System.Windows.Threading;
86
using AlphaChiTech.Virtualization;
97

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using System.ComponentModel;
2+
using System.Windows.Controls;
3+
using DataGridAsyncDemoMVVM.filtersort;
4+
using GalaSoft.MvvmLight.Command;
5+
6+
namespace DataGridAsyncDemoMVVM.converters
7+
{
8+
public class DataGridSortingEventArgsToMemberPathSortDirection : IEventArgsConverter
9+
{
10+
public object Convert(object value, object parameter)
11+
{
12+
if (!(value is DataGridSortingEventArgs sortingEventArgs)) return null;
13+
14+
var sortMemberPath = sortingEventArgs.Column.SortMemberPath;
15+
var sortDirection = sortingEventArgs.Column.SortDirection;
16+
17+
switch (sortDirection)
18+
{
19+
case null:
20+
sortDirection = ListSortDirection.Ascending;
21+
break;
22+
case ListSortDirection.Ascending:
23+
sortDirection = ListSortDirection.Descending;
24+
break;
25+
case ListSortDirection.Descending:
26+
sortDirection = null;
27+
break;
28+
}
29+
sortingEventArgs.Column.SortDirection = sortDirection;
30+
sortingEventArgs.Handled = true;
31+
32+
return new MemberPathSortingDirection {MemberPath = sortMemberPath, SortDirection = sortDirection};
33+
}
34+
}
35+
}

DataGridAsyncDemoMVVM/converters/TextChangedEventArgsToDatagridHeaderAndText.cs renamed to DataGridAsyncDemoMVVM/converters/TextChangedEventArgsToMemberPathAndText.cs

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,25 @@
1-
using System;
2-
using System.Globalization;
3-
using System.Windows;
41
using System.Windows.Controls;
52
using System.Windows.Controls.Primitives;
6-
using System.Windows.Data;
73
using DataGridAsyncDemoMVVM.filtersort;
84
using GalaSoft.MvvmLight.Command;
95

106
namespace DataGridAsyncDemoMVVM.converters
117
{
12-
public class TextChangedEventArgsToDatagridHeaderAndText : IEventArgsConverter
8+
public class TextChangedEventArgsToMemberPathAndText : IEventArgsConverter
139
{
1410
public object Convert(object value, object parameter)
1511
{
1612
if (value is TextChangedEventArgs eventArgs)
17-
{
1813
if (eventArgs.Source is TextBox textBox)
1914
{
20-
21-
DataGridColumnHeader dataGridColumnHeader = textBox.ParentOfType<DataGridColumnHeader>();
15+
var dataGridColumnHeader = textBox.ParentOfType<DataGridColumnHeader>();
2216
if (dataGridColumnHeader != null)
2317
{
24-
string columnSortMemberPath = dataGridColumnHeader.Column.SortMemberPath;
18+
var columnSortMemberPath = dataGridColumnHeader.Column.SortMemberPath;
2519
var filterText = textBox.Text;
26-
return new MemberPathFilterText{ ColumnSortMemberPath =columnSortMemberPath, FilterText= filterText };
20+
return new MemberPathFilterText {MemberPath = columnSortMemberPath, FilterText = filterText};
2721
}
2822
}
29-
}
3023
return null;
3124
}
3225
}

DataGridAsyncDemoMVVM/filtersort/MemberPathFilterText.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ namespace DataGridAsyncDemoMVVM.filtersort
22
{
33
public class MemberPathFilterText
44
{
5-
public string ColumnSortMemberPath { get; set; }
5+
public string MemberPath { get; set; }
66
public string FilterText { get; set; }
77
}
88
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using System.ComponentModel;
2+
3+
namespace DataGridAsyncDemoMVVM.filtersort
4+
{
5+
public class MemberPathSortingDirection
6+
{
7+
public string MemberPath { get; set; }
8+
public ListSortDirection? SortDirection { get; set; }
9+
}
10+
}

DataGridAsyncDemoMVVM/filtersort/ParentOfTypeExtensions.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ public static void TestNotNull(this object parameter, string parameterName)
1818
public static void TestNotEmptyString(this string parameter, string parameterName)
1919
{
2020
if (string.IsNullOrEmpty(parameter))
21-
throw new ArgumentException($@"The parameter '{parameterName}' should not be empty string.", parameterName);
21+
throw new ArgumentException($@"The parameter '{parameterName}' should not be empty string.",
22+
parameterName);
2223
}
2324
}
2425

@@ -97,10 +98,8 @@ private static DependencyObject GetParent(this DependencyObject element)
9798
{
9899
var parent = VisualTreeHelper.GetParent(element);
99100
if (parent == null)
100-
{
101101
if (element is FrameworkElement frameworkElement)
102102
parent = frameworkElement.Parent;
103-
}
104103
return parent;
105104
}
106105
}

DataGridAsyncDemoMVVM/packages.config

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<?xml version="1.0" encoding="utf-8"?>
2+
23
<packages>
34
<package id="CommonServiceLocator" version="1.3" targetFramework="net47" />
45
<package id="MvvmLightLibs" version="5.3.0.0" targetFramework="net47" />

0 commit comments

Comments
 (0)