Skip to content

Commit ed7bc1f

Browse files
committed
feat: Create AdvancedExamplesWindow and refactor MainViewModel
1 parent 000132d commit ed7bc1f

File tree

6 files changed

+293
-214
lines changed

6 files changed

+293
-214
lines changed
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
using SimpleDataGrid.Pagination;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.ComponentModel;
5+
using System.Linq;
6+
7+
namespace SimpleDataGrid.Example;
8+
9+
/// <summary>
10+
/// The view model for the advanced examples window.
11+
/// </summary>
12+
public class AdvancedExamplesViewModel : INotifyPropertyChanged
13+
{
14+
public PagedCollection<Person> People { get; }
15+
public List<int> PageSizes { get; } = [10, 25, 50, 100];
16+
17+
public bool SearchByName { get; set; } = true;
18+
public bool SearchByEmail { get; set; } = false;
19+
public bool SearchByDepartment { get; set; } = false;
20+
21+
public AdvancedExamplesViewModel()
22+
{
23+
People = new PagedCollection<Person>(10);
24+
People.SetSource(GetPeople());
25+
}
26+
27+
private static List<Person> GetPeople()
28+
{
29+
var people = new List<Person>();
30+
for (var i = 1; i <= 1000; i++)
31+
{
32+
people.Add(new Person
33+
{
34+
Id = i,
35+
Name = $"Person {i}",
36+
Age = 20 + (i % 50),
37+
Email = $"person{i}@example.com",
38+
Department = (i % 3 == 0) ? "Sales" : (i % 3 == 1) ? "Marketing" : "Engineering",
39+
IsActive = (i % 2 == 0),
40+
HireDate = DateTime.Now.AddDays(-i)
41+
});
42+
}
43+
return people;
44+
}
45+
46+
public void ApplyFilter(int minAge)
47+
{
48+
People.SetFilter("minAge", p => p.Age >= minAge);
49+
}
50+
51+
public void ApplyMaxAgeFilter(int maxAge)
52+
{
53+
People.SetFilter("maxAge", p => p.Age <= maxAge);
54+
}
55+
56+
public void ApplyNameFilter(string namePrefix)
57+
{
58+
People.SetFilter("namePrefix", p => p.Name.StartsWith(namePrefix, StringComparison.OrdinalIgnoreCase));
59+
}
60+
61+
public void RemoveFilter(string key)
62+
{
63+
People.RemoveFilter(key);
64+
}
65+
66+
public IReadOnlyCollection<string> ActiveFilters => People.GetActiveFilters();
67+
68+
public void ClearFilter()
69+
{
70+
People.ClearFilters();
71+
}
72+
73+
public event PropertyChangedEventHandler? PropertyChanged;
74+
protected virtual void OnPropertyChanged(string propertyName)
75+
{
76+
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
77+
}
78+
}

SimpleDataGrid.Example/AdvancedExamplesWindow.xaml

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,99 @@
33
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
44
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
55
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
6+
xmlns:local="clr-namespace:SimpleDataGrid.Example"
7+
xmlns:controls="clr-namespace:SimpleDataGrid.Controls;assembly=SimpleDataGrid"
8+
xmlns:converters="clr-namespace:SimpleDataGrid.Example.Converters"
69
mc:Ignorable="d"
710
Title="AdvancedExamplesWindow" Height="450" Width="800">
11+
<Window.Resources>
12+
<converters:ItemCountConverter x:Key="ItemCountConverter"/>
13+
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
14+
</Window.Resources>
15+
<Window.DataContext>
16+
<local:AdvancedExamplesViewModel />
17+
</Window.DataContext>
818
<Grid>
9-
19+
<Grid.RowDefinitions>
20+
<RowDefinition Height="Auto" />
21+
<RowDefinition Height="*" />
22+
<RowDefinition Height="Auto" />
23+
</Grid.RowDefinitions>
24+
25+
<StackPanel Grid.Row="0" Orientation="Vertical" Margin="5">
26+
<StackPanel Orientation="Horizontal">
27+
<TextBox x:Name="SearchTextBox" Width="200" Margin="5" TextChanged="SearchTextBox_TextChanged"/>
28+
<CheckBox x:Name="WildcardCheckBox" Content="Use Wildcards" VerticalAlignment="Center" Margin="5" />
29+
<ProgressBar IsIndeterminate="True" Width="20" Height="20" Margin="5" Visibility="{Binding People.IsSearching, Converter={StaticResource BooleanToVisibilityConverter}}"/>
30+
</StackPanel>
31+
<StackPanel Orientation="Horizontal" Margin="5,0,0,0">
32+
<TextBlock Text="Search In:" VerticalAlignment="Center" Margin="0,0,5,0"/>
33+
<CheckBox Content="Name" IsChecked="{Binding SearchByName}" Checked="SearchOption_Changed" Unchecked="SearchOption_Changed" Margin="0,0,5,0"/>
34+
<CheckBox Content="Email" IsChecked="{Binding SearchByEmail}" Checked="SearchOption_Changed" Unchecked="SearchOption_Changed" Margin="0,0,5,0"/>
35+
<CheckBox Content="Department" IsChecked="{Binding SearchByDepartment}" Checked="SearchOption_Changed" Unchecked="SearchOption_Changed" Margin="0,0,5,0"/>
36+
</StackPanel>
37+
<StackPanel Orientation="Horizontal">
38+
<TextBox x:Name="MinAgeTextBox" Width="50" Margin="5" />
39+
<Button Content="Filter by Min Age" Click="FilterButton_Click" Margin="5" />
40+
<TextBox x:Name="MaxAgeTextBox" Width="50" Margin="5" />
41+
<Button Content="Filter by Max Age" Click="MaxAgeFilterButton_Click" Margin="5" />
42+
<TextBox x:Name="NamePrefixTextBox" Width="100" Margin="5" />
43+
<Button Content="Filter by Name Prefix" Click="NamePrefixFilterButton_Click" Margin="5" />
44+
<Button Content="Clear Filters" Click="ClearFilterButton_Click" Margin="5" />
45+
</StackPanel>
46+
<ItemsControl ItemsSource="{Binding People.ActiveFilters}">
47+
<ItemsControl.ItemsPanel>
48+
<ItemsPanelTemplate>
49+
<StackPanel Orientation="Horizontal"/>
50+
</ItemsPanelTemplate>
51+
</ItemsControl.ItemsPanel>
52+
<ItemsControl.ItemTemplate>
53+
<DataTemplate>
54+
<StackPanel Orientation="Horizontal">
55+
<TextBlock Text="{Binding}" VerticalAlignment="Center" Margin="5,0"/>
56+
<Button Content="Remove" Click="RemoveFilterButton_Click" CommandParameter="{Binding}" Margin="5,0"/>
57+
</StackPanel>
58+
</DataTemplate>
59+
</ItemsControl.ItemTemplate>
60+
</ItemsControl>
61+
</StackPanel>
62+
63+
<controls:PagedDataGrid x:Name="PagedDataGrid" Grid.Row="1" PagedSource="{Binding People}" AutoGenerateColumns="True" />
64+
65+
<Grid Grid.Row="1" Background="#AAFFFFFF" Visibility="{Binding People.IsEmpty, Converter={StaticResource BooleanToVisibilityConverter}}">
66+
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
67+
<TextBlock Text="No items found." FontSize="24" FontWeight="Bold" Margin="0,0,0,10"/>
68+
<TextBlock Text="Try clearing your filters or search terms." FontSize="14" TextAlignment="Center"/>
69+
</StackPanel>
70+
</Grid>
71+
72+
<StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Center">
73+
<Button Content="First" Click="FirstButton_Click" Margin="5" IsEnabled="{Binding People.HasPrevious}"/>
74+
<Button Content="Previous" Click="PreviousButton_Click" Margin="5" IsEnabled="{Binding People.HasPrevious}"/>
75+
<TextBlock VerticalAlignment="Center" Margin="5">
76+
<TextBlock.Text>
77+
<MultiBinding StringFormat="Page {0} of {1}">
78+
<Binding Path="People.CurrentPage"/>
79+
<Binding Path="People.TotalPages"/>
80+
</MultiBinding>
81+
</TextBlock.Text>
82+
</TextBlock>
83+
<Button Content="Next" Click="NextButton_Click" Margin="5" IsEnabled="{Binding People.HasNext}"/>
84+
<Button Content="Last" Click="LastButton_Click" Margin="5" IsEnabled="{Binding People.HasNext}"/>
85+
<TextBlock Text="Go to page:" VerticalAlignment="Center" Margin="5,0,0,0"/>
86+
<TextBox x:Name="PageTextBox" Width="30" Margin="5,0,0,0"/>
87+
<Button Content="Go" Click="GoToPageButton_Click" Margin="5,0,0,0"/>
88+
<ComboBox Margin="10,0,0,0" ItemsSource="{Binding PageSizes}" SelectedItem="{Binding People.PageSize}"/>
89+
<TextBlock VerticalAlignment="Center" Margin="10,0,0,0">
90+
<TextBlock.Text>
91+
<MultiBinding Converter="{StaticResource ItemCountConverter}">
92+
<Binding Path="People.CurrentPageItems.Count"/>
93+
<Binding Path="People.CurrentPage"/>
94+
<Binding Path="People.TotalItems"/>
95+
<Binding Path="People.PageSize"/>
96+
</MultiBinding>
97+
</TextBlock.Text>
98+
</TextBlock>
99+
</StackPanel>
10100
</Grid>
11101
</Window>

SimpleDataGrid.Example/AdvancedExamplesWindow.xaml.cs

Lines changed: 99 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1+
using SimpleDataGrid.Controls;
2+
using System;
3+
using System.Collections.Generic;
14
using System.Windows;
5+
using System.Windows.Controls;
26

37
namespace SimpleDataGrid.Example;
48

@@ -8,4 +12,98 @@ public AdvancedExamplesWindow()
812
{
913
InitializeComponent();
1014
}
11-
}
15+
16+
private void PreviousButton_Click(object sender, RoutedEventArgs e)
17+
{
18+
var viewModel = (AdvancedExamplesViewModel)DataContext;
19+
viewModel.People.PreviousPage();
20+
}
21+
22+
private void NextButton_Click(object sender, RoutedEventArgs e)
23+
{
24+
var viewModel = (AdvancedExamplesViewModel)DataContext;
25+
viewModel.People.NextPage();
26+
}
27+
28+
private void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e)
29+
{
30+
ApplyMultiColumnSearch();
31+
}
32+
33+
private void SearchOption_Changed(object sender, RoutedEventArgs e)
34+
{
35+
ApplyMultiColumnSearch();
36+
}
37+
38+
private void ApplyMultiColumnSearch()
39+
{
40+
var viewModel = (AdvancedExamplesViewModel)DataContext;
41+
var selectors = new List<Func<Person, string>>();
42+
43+
if (viewModel.SearchByName) selectors.Add(p => p.Name);
44+
if (viewModel.SearchByEmail) selectors.Add(p => p.Email);
45+
if (viewModel.SearchByDepartment) selectors.Add(p => p.Department);
46+
47+
viewModel.People.SetSearch(selectors, SearchTextBox.Text, WildcardCheckBox.IsChecked == true, 300);
48+
}
49+
50+
private void FilterButton_Click(object sender, RoutedEventArgs e)
51+
{
52+
var viewModel = (AdvancedExamplesViewModel)DataContext;
53+
if (int.TryParse(MinAgeTextBox.Text, out var minAge))
54+
{
55+
viewModel.ApplyFilter(minAge);
56+
}
57+
}
58+
59+
private void ClearFilterButton_Click(object sender, RoutedEventArgs e)
60+
{
61+
var viewModel = (AdvancedExamplesViewModel)DataContext;
62+
viewModel.ClearFilter();
63+
}
64+
65+
private void FirstButton_Click(object sender, RoutedEventArgs e)
66+
{
67+
var viewModel = (AdvancedExamplesViewModel)DataContext;
68+
viewModel.People.GoToFirstPage();
69+
}
70+
71+
private void LastButton_Click(object sender, RoutedEventArgs e)
72+
{
73+
var viewModel = (AdvancedExamplesViewModel)DataContext;
74+
viewModel.People.GoToLastPage();
75+
}
76+
77+
private void GoToPageButton_Click(object sender, RoutedEventArgs e)
78+
{
79+
var viewModel = (AdvancedExamplesViewModel)DataContext;
80+
if (int.TryParse(PageTextBox.Text, out var page))
81+
{
82+
viewModel.People.GoToPage(page);
83+
}
84+
}
85+
86+
private void MaxAgeFilterButton_Click(object sender, RoutedEventArgs e)
87+
{
88+
var viewModel = (AdvancedExamplesViewModel)DataContext;
89+
if (int.TryParse(MaxAgeTextBox.Text, out var maxAge))
90+
{
91+
viewModel.ApplyMaxAgeFilter(maxAge);
92+
}
93+
}
94+
95+
private void NamePrefixFilterButton_Click(object sender, RoutedEventArgs e)
96+
{
97+
var viewModel = (AdvancedExamplesViewModel)DataContext;
98+
viewModel.ApplyNameFilter(NamePrefixTextBox.Text);
99+
}
100+
101+
private void RemoveFilterButton_Click(object sender, RoutedEventArgs e)
102+
{
103+
var viewModel = (AdvancedExamplesViewModel)DataContext;
104+
if (sender is Button button && button.CommandParameter is string key)
105+
{
106+
viewModel.RemoveFilter(key);
107+
}
108+
}
109+
}

SimpleDataGrid.Example/MainViewModel.cs

Lines changed: 9 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -13,23 +13,6 @@ public class MainViewModel
1313
/// Gets the paged collection of people.
1414
/// </summary>
1515
public PagedCollection<Person> People { get; }
16-
/// <summary>
17-
/// Gets a list of available page sizes.
18-
/// </summary>
19-
public List<int> PageSizes { get; } = [10, 25, 50, 100];
20-
21-
/// <summary>
22-
/// Gets or sets a value indicating whether to search by name.
23-
/// </summary>
24-
public bool SearchByName { get; set; } = true;
25-
/// <summary>
26-
/// Gets or sets a value indicating whether to search by email.
27-
/// </summary>
28-
public bool SearchByEmail { get; set; } = false;
29-
/// <summary>
30-
/// Gets or sets a value indicating whether to search by department.
31-
/// </summary>
32-
public bool SearchByDepartment { get; set; } = false;
3316

3417
/// <summary>
3518
/// Initializes a new instance of the <see cref="MainViewModel"/> class.
@@ -49,55 +32,6 @@ private static List<Person> GetPeople()
4932
}
5033
return people;
5134
}
52-
53-
/// <summary>
54-
/// Applies a minimum age filter to the people collection.
55-
/// </summary>
56-
/// <param name="minAge">The minimum age to filter by.</param>
57-
public void ApplyFilter(int minAge)
58-
{
59-
People.SetFilter("minAge", p => p.Age >= minAge);
60-
}
61-
62-
/// <summary>
63-
/// Applies a maximum age filter to the people collection.
64-
/// </summary>
65-
/// <param name="maxAge">The maximum age to filter by.</param>
66-
public void ApplyMaxAgeFilter(int maxAge)
67-
{
68-
People.SetFilter("maxAge", p => p.Age <= maxAge);
69-
}
70-
71-
/// <summary>
72-
/// Applies a name prefix filter to the people collection.
73-
/// </summary>
74-
/// <param name="namePrefix">The name prefix to filter by.</param>
75-
public void ApplyNameFilter(string namePrefix)
76-
{
77-
People.SetFilter("namePrefix", p => p.Name.StartsWith(namePrefix, StringComparison.OrdinalIgnoreCase));
78-
}
79-
80-
/// <summary>
81-
/// Removes a filter from the people collection.
82-
/// </summary>
83-
/// <param name="key">The key of the filter to remove.</param>
84-
public void RemoveFilter(string key)
85-
{
86-
People.RemoveFilter(key);
87-
}
88-
89-
/// <summary>
90-
/// Gets a read-only collection of the active filter keys.
91-
/// </summary>
92-
public IReadOnlyCollection<string> ActiveFilters => People.GetActiveFilters();
93-
94-
/// <summary>
95-
/// Clears all filters from the people collection.
96-
/// </summary>
97-
public void ClearFilter()
98-
{
99-
People.ClearFilters();
100-
}
10135
}
10236

10337
/// <summary>
@@ -125,4 +59,12 @@ public class Person
12559
/// Gets or sets the department of the person.
12660
/// </summary>
12761
public string Department { get; set; } = string.Empty;
128-
}
62+
/// <summary>
63+
/// Gets or sets a value indicating whether the person is active.
64+
/// </summary>
65+
public bool IsActive { get; set; }
66+
/// <summary>
67+
/// Gets or sets the hire date of the person.
68+
/// </summary>
69+
public DateTime HireDate { get; set; }
70+
}

0 commit comments

Comments
 (0)