Move filtering into SyncBindingSource
This commit is contained in:
parent
3a5ef999f0
commit
255c0a3359
@ -1,5 +1,8 @@
|
|||||||
using System;
|
using ApplicationServices;
|
||||||
|
using Dinah.Core.DataBinding;
|
||||||
|
using System;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
@ -17,7 +20,34 @@ namespace LibationWinForms
|
|||||||
public SyncBindingSource(object dataSource, string dataMember) : base(dataSource, dataMember)
|
public SyncBindingSource(object dataSource, string dataMember) : base(dataSource, dataMember)
|
||||||
=> syncContext = SynchronizationContext.Current;
|
=> syncContext = SynchronizationContext.Current;
|
||||||
|
|
||||||
protected override void OnListChanged(ListChangedEventArgs e)
|
public override bool SupportsFiltering => true;
|
||||||
|
public override string Filter { get => filterString; set => SetFilter(value); }
|
||||||
|
|
||||||
|
private string filterString;
|
||||||
|
|
||||||
|
private void SetFilter(string searchString)
|
||||||
|
{
|
||||||
|
if (searchString != filterString)
|
||||||
|
RemoveFilter();
|
||||||
|
|
||||||
|
filterString = searchString;
|
||||||
|
|
||||||
|
var searchResults = SearchEngineCommands.Search(searchString);
|
||||||
|
var productIds = searchResults.Docs.Select(d => d.ProductId).ToList();
|
||||||
|
|
||||||
|
|
||||||
|
var allItems = ((SortableBindingList<GridEntry>)DataSource).InnerList;
|
||||||
|
var filterList = productIds.Join(allItems, s => s, ge => ge.AudibleProductId, (pid, ge) => ge).ToList();
|
||||||
|
|
||||||
|
((SortableBindingList<GridEntry>)DataSource).SetFilteredItems(filterList);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void RemoveFilter()
|
||||||
|
{
|
||||||
|
((SortableBindingList<GridEntry>)DataSource).RemoveFilter();
|
||||||
|
base.RemoveFilter();
|
||||||
|
}
|
||||||
|
protected override void OnListChanged(ListChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if (syncContext is not null)
|
if (syncContext is not null)
|
||||||
syncContext.Send(_ => base.OnListChanged(e), null);
|
syncContext.Send(_ => base.OnListChanged(e), null);
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@ -55,8 +56,6 @@ namespace LibationWinForms
|
|||||||
|
|
||||||
EnableDoubleBuffering();
|
EnableDoubleBuffering();
|
||||||
|
|
||||||
// sorting breaks filters. must reapply filters after sorting
|
|
||||||
_dataGridView.Sorted += reapplyFilter;
|
|
||||||
_dataGridView.CellContentClick += DataGridView_CellContentClick;
|
_dataGridView.CellContentClick += DataGridView_CellContentClick;
|
||||||
|
|
||||||
this.Load += ProductsGrid_Load;
|
this.Load += ProductsGrid_Load;
|
||||||
@ -184,14 +183,13 @@ namespace LibationWinForms
|
|||||||
else
|
else
|
||||||
bindToGrid(orderedBooks);
|
bindToGrid(orderedBooks);
|
||||||
|
|
||||||
// re-apply previous filter
|
|
||||||
reapplyFilter();
|
|
||||||
|
|
||||||
if (!hasBeenDisplayed)
|
if (!hasBeenDisplayed)
|
||||||
{
|
{
|
||||||
hasBeenDisplayed = true;
|
hasBeenDisplayed = true;
|
||||||
InitialLoaded?.Invoke(this, new());
|
InitialLoaded?.Invoke(this, new());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bindToGrid(List<DataLayer.LibraryBook> orderedBooks)
|
private void bindToGrid(List<DataLayer.LibraryBook> orderedBooks)
|
||||||
@ -230,7 +228,6 @@ namespace LibationWinForms
|
|||||||
private GridEntry toGridEntry(DataLayer.LibraryBook libraryBook)
|
private GridEntry toGridEntry(DataLayer.LibraryBook libraryBook)
|
||||||
{
|
{
|
||||||
var entry = new GridEntry(libraryBook);
|
var entry = new GridEntry(libraryBook);
|
||||||
entry.Committed += reapplyFilter;
|
|
||||||
// see also notes in Libation/Source/__ARCHITECTURE NOTES.txt :: MVVM
|
// see also notes in Libation/Source/__ARCHITECTURE NOTES.txt :: MVVM
|
||||||
entry.LibraryBookUpdated += (sender, _) => _dataGridView.InvalidateRow(_dataGridView.GetRowIdOfBoundItem((GridEntry)sender));
|
entry.LibraryBookUpdated += (sender, _) => _dataGridView.InvalidateRow(_dataGridView.GetRowIdOfBoundItem((GridEntry)sender));
|
||||||
return entry;
|
return entry;
|
||||||
@ -240,53 +237,26 @@ namespace LibationWinForms
|
|||||||
|
|
||||||
#region Filter
|
#region Filter
|
||||||
|
|
||||||
private string _filterSearchString;
|
|
||||||
private void reapplyFilter(object _ = null, EventArgs __ = null) => Filter(_filterSearchString);
|
|
||||||
public void Filter(string searchString)
|
public void Filter(string searchString)
|
||||||
{
|
{
|
||||||
// empty string is valid. null is not
|
|
||||||
if (searchString is null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_filterSearchString = searchString;
|
|
||||||
|
|
||||||
if (_dataGridView.Rows.Count == 0)
|
if (_dataGridView.Rows.Count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var initVisible = getVisible().Count();
|
if (string.IsNullOrEmpty(searchString))
|
||||||
|
gridEntryBindingSource.RemoveFilter();
|
||||||
|
else
|
||||||
|
gridEntryBindingSource.Filter = searchString;
|
||||||
|
|
||||||
var searchResults = SearchEngineCommands.Search(searchString);
|
|
||||||
var productIds = searchResults.Docs.Select(d => d.ProductId).ToList();
|
|
||||||
|
|
||||||
// https://stackoverflow.com/a/18942430
|
VisibleCountChanged?.Invoke(this, bindingList.Count);
|
||||||
var bindingContext = BindingContext[_dataGridView.DataSource];
|
|
||||||
bindingContext.SuspendBinding();
|
|
||||||
{
|
|
||||||
this.UIThreadSync(() =>
|
|
||||||
{
|
|
||||||
for (var r = _dataGridView.RowCount - 1; r >= 0; r--)
|
|
||||||
_dataGridView.Rows[r].Visible = productIds.Contains(getGridEntry(r).AudibleProductId);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Causes repainting of the DataGridView
|
|
||||||
bindingContext.ResumeBinding();
|
|
||||||
|
|
||||||
var endVisible = getVisible().Count();
|
|
||||||
if (initVisible != endVisible)
|
|
||||||
VisibleCountChanged?.Invoke(this, endVisible);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private IEnumerable<DataGridViewRow> getVisible()
|
internal List<LibraryBook> GetVisible()
|
||||||
=> _dataGridView
|
=> bindingList
|
||||||
.AsEnumerable()
|
.InnerList
|
||||||
.Where(row => row.Visible);
|
.Select(row => row.LibraryBook)
|
||||||
|
|
||||||
internal List<DataLayer.LibraryBook> GetVisible()
|
|
||||||
=> getVisible()
|
|
||||||
.Select(row => ((GridEntry)row.DataBoundItem).LibraryBook)
|
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
private GridEntry getGridEntry(int rowIndex) => _dataGridView.GetBoundItem<GridEntry>(rowIndex);
|
private GridEntry getGridEntry(int rowIndex) => _dataGridView.GetBoundItem<GridEntry>(rowIndex);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user