Skip to content

Commit

Permalink
feat: resort on observable
Browse files Browse the repository at this point in the history
  • Loading branch information
giard-alexandre committed Oct 17, 2024
1 parent dc97e7f commit fb0cb4f
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 11 deletions.
21 changes: 20 additions & 1 deletion samples/SampleApp/ViewModels/MainWindowViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.ObjectModel;
using System.Reactive;
using System.Reactive.Linq;
using System.Text.Json;

Expand All @@ -18,7 +19,6 @@ namespace SampleApp.ViewModels;

public class MainWindowViewModel : ReactiveObject {
private readonly JsonSerializerOptions _jsonOptions = new(JsonSerializerOptions.Default) { WriteIndented = true };
private string? _filterText;

public MainWindowViewModel() {
//Set the randomizer seed to generate repeatable data sets.
Expand All @@ -40,9 +40,21 @@ public MainWindowViewModel() {

var filteredData = data.Filter(searchFilter);

var preSortDirectionStream = this.WhenValueChanged(t => t.PreSortDescending)
.Select(b => b ? SortDirection.Descending : SortDirection.Ascending)
.Do(x => {
if (DataSource is not null) {
DataSource.Options.PreColumnSort =
new SortExpressionComparer<Person> {
new SortExpression<Person>(person => person.IsChecked, x)
};
}
});

DataSource = new DynamicFlatTreeDataGridSource<Person, int>(filteredData, RxApp.MainThreadScheduler, new DynamicTreeDataGridSourceOptions<Person>() {
PreColumnSort = SortExpressionComparer<Person>.Descending(person => person.IsChecked),
PostColumnSort = SortExpressionComparer<Person>.Descending(person => person.Money),
Resorter = preSortDirectionStream.Select(_ => Unit.Default),
}) {
Columns = {
new DynamicTextColumn<Person, int>("Id", "Id", person => person.Id),
Expand All @@ -59,11 +71,18 @@ public MainWindowViewModel() {

public DynamicFlatTreeDataGridSource<Person, int> DataSource { get; set; }

private string? _filterText;
public string? FilterText {
get => _filterText;
set => this.RaiseAndSetIfChanged(ref _filterText, value);
}

private bool _preSortDescending = true;
public bool PreSortDescending {
get => _preSortDescending;
set => this.RaiseAndSetIfChanged(ref _preSortDescending, value);
}

public void PrintColumnStates() {
Console.WriteLine(JsonSerializer.Serialize(DataSource.GetGridState(), _jsonOptions));
}
Expand Down
18 changes: 16 additions & 2 deletions samples/SampleApp/Views/MainWindow.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,23 @@

<DockPanel>
<StackPanel Orientation="Horizontal" DockPanel.Dock="Top">
<Label Target="FilterTextBox">Filter Name: </Label>
<TextBox Name="FilterTextBox" Text="{Binding FilterText}" Width="200" />
<StackPanel.Styles>
<Style Selector="StackPanel">
<Setter Property="Orientation" Value="Horizontal" />
<Setter Property="Margin" Value="5" />
</Style>
</StackPanel.Styles>
<StackPanel>
<Label Target="FilterTextBox">Filter Name: </Label>
<TextBox Name="FilterTextBox" Text="{Binding FilterText}" Width="200" />
</StackPanel>
<Button Content="Print Column States To Console" Command="{Binding PrintColumnStates}" />
<StackPanel>
<Label Target="SortDirectionToggle">Pre-Sort Descending</Label>
<ToggleSwitch Name="SortDirectionToggle" OffContent="Ascending" OnContent="Descending"
IsChecked="{Binding PreSortDescending}" />
</StackPanel>

</StackPanel>
<dynamicTreeDataGrid:DynamicTreeDataGrid Source="{Binding DataSource}">
<TreeDataGrid.Resources>
Expand Down
13 changes: 6 additions & 7 deletions src/DynamicTreeDataGrid/DynamicFlatTreeDataGridSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ public class DynamicFlatTreeDataGridSource<TModel, TModelKey> : NotifyingBase, I
private readonly IObservable<Func<TModel, bool>> _itemsFilter;
private readonly IObservable<IComparer<TModel>> _sort;
private readonly BehaviorSubject<IComparer<TModel>?> _columnsSortSource = new(null);
private readonly DynamicTreeDataGridSourceOptions<TModel> _options;

public DynamicFlatTreeDataGridSource(IObservable<IChangeSet<TModel, TModelKey>> changes,
IScheduler mainThreadScheduler) : this(changes, mainThreadScheduler,
Expand All @@ -42,25 +41,24 @@ public DynamicFlatTreeDataGridSource(IObservable<IChangeSet<TModel, TModelKey>>
public DynamicFlatTreeDataGridSource(IObservable<IChangeSet<TModel, TModelKey>> changes,
IScheduler mainThreadScheduler,
DynamicTreeDataGridSourceOptions<TModel> options) {
_options = options;
Options = options;
_itemsFilter = _filterSource;
TotalCount = changes.Count();

// Setup Sort notifications
_sort = _columnsSortSource

// Trigger re-sorting if either column sort changes or the resorter from _options fires.
.CombineLatest(_options.Resorter.StartWith(Unit.Default), resultSelector: (comparer, _) => comparer)
// Trigger re-sorting if either column sort changes or the resorter from Options fires.
.CombineLatest(Options.Resorter.StartWith(Unit.Default), resultSelector: (comparer, _) => comparer)
.Do(comparer => _comparer = comparer)
.Select(comparer =>
new CombinedComparer<TModel>(_options.PreColumnSort, comparer, _options.PostColumnSort));
.Select(comparer => new CombinedComparer<TModel>(Options.PreColumnSort, comparer, Options.PostColumnSort));
var sortDisposable = _sort.Subscribe(comparer => { Sorted?.Invoke(); });

var filteredChanges = changes.Filter(_itemsFilter);
FilteredCount = filteredChanges.Count();

var disposable = filteredChanges.DeferUntilLoaded()
.Sort(_sort, sortOptimisations: _options.SortOptimisations) // Use SortAndBind?
.Sort(_sort, sortOptimisations: Options.SortOptimisations) // Use SortAndBind?
.ObserveOn(mainThreadScheduler)
.Bind(out _items)
.DisposeMany()
Expand All @@ -79,6 +77,7 @@ public DynamicFlatTreeDataGridSource(IObservable<IChangeSet<TModel, TModelKey>>
public IObservable<int> TotalCount { get; }
IDynamicColumns IDynamicTreeDataGridSource.Columns => Columns;
IColumns ITreeDataGridSource.Columns => Columns.DisplayedColumns;
public DynamicTreeDataGridSourceOptions<TModel> Options { get; }

public GridState GetGridState() => new() { ColumnStates = Columns.GetColumnStates() };

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public DynamicHierarchicalTreeDataGridSource(IObservable<IChangeSet<TModel, TMod
// TODO: Setup Sorted event for treeDataGridSourceImplementation?
}

public DynamicTreeDataGridSourceOptions<TModel> Options { get; }
public new DynamicColumnList<TModel> Columns { get; } = [];

public IObservable<int> FilteredCount { get; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
namespace DynamicTreeDataGrid.Models;

public interface IDynamicTreeDataGridSource<TModel> : ITreeDataGridSource<TModel>, IDynamicTreeDataGridSource {
// TODO: Add filter, state, maybe sort?
public DynamicTreeDataGridSourceOptions<TModel> Options { get; }
}

0 comments on commit fb0cb4f

Please sign in to comment.