A powerful and simple DataGrid for WPF applications, offering seamless pagination, advanced filtering, and robust searching capabilities. Easily integrate and manage large datasets with a modern UI.
- Pagination: Easily page through large datasets with comprehensive controls including
NextPage,PreviousPage,GoToPage,GoToFirstPage,GoToLastPage, andResetToFirstPage. Supports configurable page sizes and provides properties likeTotalItems,IsEmpty,HasItems, andIsSourceEmptyfor detailed state management. - Filtering: Filter data based on custom criteria using
AddFilter,SetFilter,RemoveFilter, andClearFilters. Supports named filters for easy management and retrieval of active filters. - Searching: Robust search functionality with
SetSearchAsync(OR logic for multiple selectors) andSetSearchAllAsync(AND logic for multiple selectors). Supports wildcards (*and?), debouncing for efficient input handling, and anIsSearchingproperty to indicate active search operations. - Sorting: Sort data by clicking on column headers or programmatically using
SetSortandClearSort. TheIsSortedproperty indicates the current sort status. - Empty State Support: Provides clear feedback when no items are found after filtering or searching, leveraging
IsEmptyandHasItemsproperties. - Observability Events: Exposes a rich set of events including
PageSizeChanged,SortChanged,FilterChanged,PageChanged,SourceChanged, andSearchChangedfor reactive UI updates. - Resource Management: Implements
IDisposablefor proper cleanup of resources, particularly for search debouncing mechanisms.
You can install the SimpleDataGrid NuGet package using either the .NET CLI or the NuGet Package Manager.
dotnet add package SimpleDataGridInstall-Package SimpleDataGrid- Install the
SimpleDataGridNuGet package. - Add the
PagedDataGridcontrol to your XAML. - Create a
PagedCollectionand bind it to thePagedSourceproperty of thePagedDataGrid.
<Windowx:Class="SimpleDataGrid.Example.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local="clr-namespace:SimpleDataGrid.Example"xmlns:controls="clr-namespace:SimpleDataGrid.Controls;assembly=SimpleDataGrid"mc:Ignorable="d"Title="MainWindow"Height="450"Width="800">
<Window.DataContext>
<local:MainViewModel />
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinitionHeight="Auto" />
<RowDefinitionHeight="*" />
<RowDefinitionHeight="Auto" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0"Orientation="Horizontal"Margin="5">
<TextBoxx:Name="SearchTextBox"Width="200"Margin="5"TextChanged="SearchTextBox_TextChanged"/>
<ButtonContent="Search"Click="SearchButton_Click"Margin="5" />
<CheckBoxx:Name="WildcardCheckBox"Content="Use Wildcards"VerticalAlignment="Center"Margin="5" />
<ButtonContent="Advanced Examples"Click="AdvancedExamplesButton_Click"Margin="5"/>
</StackPanel>
<controls:PagedDataGridx:Name="PagedDataGrid" Grid.Row="1"PagedSource="{Binding People}"AutoGenerateColumns="True" />
<StackPanel Grid.Row="2"Orientation="Horizontal"HorizontalAlignment="Center">
<ButtonContent="Previous"Click="PreviousButton_Click"Margin="5" />
<TextBlockText="{Binding People.CurrentPage}"VerticalAlignment="Center"Margin="5" />
<TextBlockText="/"VerticalAlignment="Center" />
<TextBlockText="{Binding People.TotalPages}"VerticalAlignment="Center"Margin="5" />
<ButtonContent="Next"Click="NextButton_Click"Margin="5" />
</StackPanel>
</Grid>
</Window>publicpartialclassMainWindow:Window{publicMainWindow(){InitializeComponent();}privatevoidPreviousButton_Click(objectsender,RoutedEventArgse){varviewModel=(MainViewModel)DataContext;viewModel.People.PreviousPage();}privatevoidNextButton_Click(objectsender,RoutedEventArgse){varviewModel=(MainViewModel)DataContext;viewModel.People.NextPage();}privatevoidSearchTextBox_TextChanged(objectsender,TextChangedEventArgse){varviewModel=(MainViewModel)DataContext;viewModel.People.SetSearch(p =>p.Name,SearchTextBox.Text,WildcardCheckBox.IsChecked==true,300);}privatevoidSearchButton_Click(objectsender,RoutedEventArgse){varviewModel=(MainViewModel)DataContext;viewModel.People.SetSearch(p =>p.Name,SearchTextBox.Text,WildcardCheckBox.IsChecked==true);}privatevoidAdvancedExamplesButton_Click(objectsender,RoutedEventArgse){varadvancedExamplesWindow=newAdvancedExamplesWindow();advancedExamplesWindow.Show();}}publicclassMainViewModel{publicPagedCollection<Person>People{get;}publicMainViewModel(){People=newPagedCollection<Person>(10);People.SetSource(GetPeople());}privatestaticList<Person>GetPeople(){varpeople=newList<Person>();for(vari=1;i<=100;i++){people.Add(newPerson{Id=i,Name=$"Person {i}",Age=20+(i%50),Email=$"person{i}@example.com",Department=(i%2==0)?"Sales":"Marketing"});}returnpeople;}}publicclassPerson{publicintId{get;set;}publicstringName{get;set;}=string.Empty;publicintAge{get;set;}publicstringEmail{get;set;}=string.Empty;publicstringDepartment{get;set;}=string.Empty;publicboolIsActive{get;set;}publicDateTimeHireDate{get;set;}}
## UsageExamples
Here are some examples of how to use the `PagedCollection` for advanced filteringand searching:
### Basic Setup
```csharp
publicclassMyViewModel{publicPagedCollection<MyItem>Items{get;}publicMyViewModel(){Items=newPagedCollection<MyItem>(pageSize:20);Items.SetSource(LoadMyItems());}privateList<MyItem>LoadMyItems()=>/* ... load your data ... */newList<MyItem>();}publicclassMyItem{publicintId{get;set;}publicstringName{get;set;}=string.Empty;publicstringCategory{get;set;}=string.Empty;publicdecimalPrice{get;set;}}// Add a filter for items in a specific categoryItems.SetFilter("CategoryFilter", item =>item.Category=="Electronics");// Remove a filterItems.RemoveFilter("CategoryFilter");// Clear all filtersItems.ClearFilters();// Search for a term in Name OR Category, with debouncingawaitItems.SetSearchAsync(selectors:newFunc<MyItem,string>[]{ item =>item.Name, item =>item.Category},term:"laptop",useWildcards:true,debounceMilliseconds:300);// Clear searchawaitItems.ClearSearchAsync();// Search for a term in Name AND Category, with debouncingawaitItems.SetSearchAllAsync(selectors:newFunc<MyItem,string>[]{ item =>item.Name, item =>item.Category},term:"gaming",useWildcards:false,debounceMilliseconds:300);// Sort by Price in ascending orderItems.SetSort(item =>item.Price,ascending:true);// Clear sortingItems.ClearSort();// Go to the next pageItems.NextPage();// Go to a specific pageItems.GoToPage(5);// Change page sizeItems.SetPageSize(10);The SimpleDataGrid.Example project demonstrates various features of the SimpleDataGrid library. It includes a basic MainWindow for quick usage and an AdvancedExamplesWindow for showcasing more complex functionalities.
To run the example project:
dotnet run --project SimpleDataGrid.ExampleFor detailed information on performance characteristics and best practices, refer to the PERFORMANCE.md document.
This project is licensed under the MIT License. See the LICENSE file for details.