Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
DynamicCollectionView.cs
1using System;
4using System.Collections.ObjectModel;
5using System.Collections.Specialized;
6using System.Linq;
7using System.Reflection;
8using Microsoft.Maui.Controls;
9
11{
15 public enum SortDirection
16 {
20 Ascending,
24 Descending
25 }
26
35 public class DynamicCollectionView : CollectionView
36 {
37 // OriginalItemsSource: the unmodified source collection.
38 public static readonly BindableProperty OriginalItemsSourceProperty =
39 BindableProperty.Create(
40 nameof(OriginalItemsSource),
41 typeof(IEnumerable),
43 default(IEnumerable),
44 propertyChanged: OnOriginalItemsSourceChanged);
45
46 public IEnumerable OriginalItemsSource
47 {
48 get => (IEnumerable)this.GetValue(OriginalItemsSourceProperty);
49 set => this.SetValue(OriginalItemsSourceProperty, value);
50 }
51
52 // Filter: A predicate to filter items.
53 public static readonly BindableProperty FilterProperty =
54 BindableProperty.Create(
55 nameof(Filter),
56 typeof(Predicate<object>),
58 default(Predicate<object>),
59 propertyChanged: OnFilterChanged);
60
61 public Predicate<object> Filter
62 {
63 get => (Predicate<object>)this.GetValue(FilterProperty);
64 set => this.SetValue(FilterProperty, value);
65 }
66
67 // SortComparison: A comparison delegate to sort items.
68 public static readonly BindableProperty SortComparisonProperty =
69 BindableProperty.Create(
70 nameof(SortComparison),
71 typeof(Comparison<object>),
73 default(Comparison<object>),
74 propertyChanged: OnSortComparisonChanged);
75
76 public Comparison<object> SortComparison
77 {
78 get => (Comparison<object>)this.GetValue(SortComparisonProperty);
79 set => this.SetValue(SortComparisonProperty, value);
80 }
81
82 // SortPropertyName: The name of the property to sort by.
83 public static readonly BindableProperty SortPropertyNameProperty =
84 BindableProperty.Create(
85 nameof(SortPropertyName),
86 typeof(string),
88 default(string),
89 propertyChanged: OnSortPropertyNameChanged);
90
91 public string SortPropertyName
92 {
93 get => (string)this.GetValue(SortPropertyNameProperty);
94 set => this.SetValue(SortPropertyNameProperty, value);
95 }
96
97 // SortDirection: Ascending or Descending sort.
98 public static readonly BindableProperty SortDirectionProperty =
99 BindableProperty.Create(
100 nameof(SortDirection),
101 typeof(SortDirection),
102 typeof(DynamicCollectionView),
103 SortDirection.Ascending,
104 propertyChanged: OnSortDirectionChanged);
105
107 {
108 get => (SortDirection)this.GetValue(SortDirectionProperty);
109 set => this.SetValue(SortDirectionProperty, value);
110 }
111
112 // Handle changes to the original items source.
113 private static void OnOriginalItemsSourceChanged(BindableObject bindable, object oldValue, object newValue)
114 {
116
117 // Unsubscribe from previous collection changes if applicable.
118 if (oldValue is INotifyCollectionChanged OldNotify)
119 {
120 OldNotify.CollectionChanged -= Control.OriginalItemsSource_CollectionChanged;
121 }
122
123 // Subscribe to the new collection if it supports notifications.
124 if (newValue is INotifyCollectionChanged NewNotify)
125 {
126 NewNotify.CollectionChanged += Control.OriginalItemsSource_CollectionChanged;
127 }
128
129 Control.ApplyFilterAndSort();
130 }
131
132 // When the underlying collection changes, refresh the view.
133 private void OriginalItemsSource_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
134 {
135 this.ApplyFilterAndSort();
136 }
137
138 // Handle changes to the Filter property.
139 private static void OnFilterChanged(BindableObject bindable, object oldValue, object newValue)
140 {
142 Control.ApplyFilterAndSort();
143 }
144
145 // Handle changes to the SortComparison property.
146 private static void OnSortComparisonChanged(BindableObject bindable, object oldValue, object newValue)
147 {
149 Control.ApplyFilterAndSort();
150 }
151
152 // Handle changes to the SortPropertyName property.
153 private static void OnSortPropertyNameChanged(BindableObject bindable, object oldValue, object newValue)
154 {
156 Control.ApplyFilterAndSort();
157 }
158
159 // Handle changes to the SortDirection property.
160 private static void OnSortDirectionChanged(BindableObject bindable, object oldValue, object newValue)
161 {
163 Control.ApplyFilterAndSort();
164 }
165
169 private void ApplyFilterAndSort()
170 {
171 if (this.OriginalItemsSource is null)
172 {
173 base.ItemsSource = null;
174 return;
175 }
176
177 // Cast the original items to object.
178 IEnumerable<object> Items = this.OriginalItemsSource.Cast<object>();
179
180 // Apply filtering if a predicate is provided.
181 if (this.Filter is not null)
182 {
183 Items = Items.Where(item => this.Filter(item));
184 }
185
186 // Apply sorting.
187 // Priority: if a SortComparison is provided, use it. Otherwise, if SortPropertyName is set, use reflection.
188 if (this.SortComparison is not null)
189 {
190 Items = Items.OrderBy(item => item, Comparer<object>.Create(this.SortComparison));
191 }
192 else if (!string.IsNullOrWhiteSpace(this.SortPropertyName))
193 {
194 if (this.SortDirection == SortDirection.Ascending)
195 {
196 Items = Items.OrderBy(item => GetPropertyValue(item, this.SortPropertyName));
197 }
198 else
199 {
200 Items = Items.OrderByDescending(item => GetPropertyValue(item, this.SortPropertyName));
201 }
202 }
203
204 // Create an observable collection for the filtered/sorted items.
205 ObservableCollection<object> TransformedCollection = new ObservableCollection<object>(Items);
206
207 // Set the base ItemsSource to the new collection.
208 base.ItemsSource = TransformedCollection;
209 }
210
214 private static object? GetPropertyValue(object obj, string propertyName)
215 {
216 if (obj is null || string.IsNullOrWhiteSpace(propertyName))
217 return null;
218
219 PropertyInfo? Prop = obj.GetType().GetProperty(propertyName);
220 return Prop?.GetValue(obj, null);
221 }
222 }
223}
A CollectionView that supports dynamic filtering and sorting of its items.
SortDirection
Represents the direction in which sorting is performed.