Skip to content

Commit d80d679

Browse files
committed
feat: Add search debouncing support
1 parent 0b7245a commit d80d679

File tree

3 files changed

+51
-5
lines changed

3 files changed

+51
-5
lines changed

SimpleDataGrid.Example/MainWindow.xaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@
2525

2626
<StackPanel Grid.Row="0" Orientation="Vertical" Margin="5">
2727
<StackPanel Orientation="Horizontal">
28-
<TextBox x:Name="SearchTextBox" Width="200" Margin="5" />
29-
<Button Content="Search" Click="SearchButton_Click" Margin="5" />
28+
<TextBox x:Name="SearchTextBox" Width="200" Margin="5" TextChanged="SearchTextBox_TextChanged"/>
3029
<CheckBox x:Name="WildcardCheckBox" Content="Use Wildcards" VerticalAlignment="Center" Margin="5" />
30+
<ProgressBar IsIndeterminate="True" Width="20" Height="20" Margin="5" Visibility="{Binding People.IsSearching, Converter={StaticResource BooleanToVisibilityConverter}}"/>
3131
</StackPanel>
3232
<StackPanel Orientation="Horizontal">
3333
<TextBox x:Name="MinAgeTextBox" Width="50" Margin="5" />

SimpleDataGrid.Example/MainWindow.xaml.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ private void NextButton_Click(object sender, RoutedEventArgs e)
2020
viewModel.People.NextPage();
2121
}
2222

23-
private void SearchButton_Click(object sender, RoutedEventArgs e)
23+
private void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e)
2424
{
2525
var viewModel = (MainViewModel)DataContext;
26-
viewModel.People.SetSearch(p => p.Name, SearchTextBox.Text, WildcardCheckBox.IsChecked == true);
26+
viewModel.People.SetSearch(p => p.Name, SearchTextBox.Text, WildcardCheckBox.IsChecked == true, 300);
2727
}
2828

2929
private void FilterButton_Click(object sender, RoutedEventArgs e)

SimpleDataGrid/Pagination/PagedCollection.cs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.ComponentModel;
22
using System.Linq;
33
using System.Text.RegularExpressions;
4+
using System.Windows;
45

56
namespace SimpleDataGrid.Pagination;
67

@@ -33,12 +34,30 @@ public int PageSize
3334
private Func<T, string>? _searchSelector;
3435
private string? _searchTerm;
3536
private bool _useWildcards;
37+
private System.Threading.Timer? _debounceTimer;
38+
private bool _isSearching;
3639

3740
/// <summary>
3841
/// Gets a value indicating whether the collection is sorted.
3942
/// </summary>
4043
public bool IsSorted => _sorts.Count > 0;
4144

45+
/// <summary>
46+
/// Gets a value indicating whether a search operation is currently in progress.
47+
/// </summary>
48+
public bool IsSearching
49+
{
50+
get => _isSearching;
51+
private set
52+
{
53+
if (_isSearching != value)
54+
{
55+
_isSearching = value;
56+
OnPropertyChanged(nameof(IsSearching));
57+
}
58+
}
59+
}
60+
4261
/// <summary>
4362
/// Occurs when the sorting changes.
4463
/// </summary>
@@ -142,11 +161,38 @@ public void ClearFilters()
142161
/// <param name="selector">A function that returns the string representation of the object to search.</param>
143162
/// <param name="term">The search term.</param>
144163
/// <param name="useWildcards">A value indicating whether to use wildcards in the search term.</param>
145-
public void SetSearch(Func<T, string> selector, string? term, bool useWildcards = false)
164+
/// <param name="debounceMilliseconds">Optional. The number of milliseconds to debounce the search. If 0, no debouncing occurs.</param>
165+
public void SetSearch(Func<T, string> selector, string? term, bool useWildcards = false, int debounceMilliseconds = 0)
146166
{
147167
_searchSelector = selector;
148168
_searchTerm = term;
149169
_useWildcards = useWildcards;
170+
171+
if (debounceMilliseconds > 0)
172+
{
173+
IsSearching = true;
174+
_debounceTimer?.Dispose();
175+
_debounceTimer = new System.Threading.Timer(_ =>
176+
{
177+
System.Windows.Application.Current.Dispatcher.Invoke(ApplyFiltering);
178+
IsSearching = false;
179+
}, null, debounceMilliseconds, System.Threading.Timeout.Infinite);
180+
}
181+
else
182+
{
183+
ApplyFiltering();
184+
SearchChanged?.Invoke(this, EventArgs.Empty);
185+
}
186+
}
187+
188+
/// <summary>
189+
/// Clears the search criteria from the collection.
190+
/// </summary>
191+
public void ClearSearch()
192+
{
193+
_searchSelector = null;
194+
_searchTerm = null;
195+
_useWildcards = false;
150196
ApplyFiltering();
151197
SearchChanged?.Invoke(this, EventArgs.Empty);
152198
}

0 commit comments

Comments
 (0)