Vereinsmeisterschaften  22aa7800eae54b428d40e835886cefe1fdefdfdf
This is a software that can be used to manage the internal competition of the swimming club Illertissen called "Vereinsmeisterschaften".
Loading...
Searching...
No Matches
DataGridBehavior.cs
1using System.Windows.Controls.Primitives;
3using System.Windows.Media;
5using System.ComponentModel;
6using System.Windows.Input;
7
9{
14 public class DataGridBehavior
15 {
16 #region DisplayRowNumber
17
21 public static DependencyProperty DisplayRowNumberProperty =
22 DependencyProperty.RegisterAttached("DisplayRowNumber",
23 typeof(bool),
24 typeof(DataGridBehavior),
25 new FrameworkPropertyMetadata(false, OnDisplayRowNumberChanged));
26
32 public static bool GetDisplayRowNumber(DependencyObject obj)
33 {
34 return (bool)obj.GetValue(DisplayRowNumberProperty);
35 }
36
42 public static void SetDisplayRowNumber(DependencyObject obj, bool value)
43 {
44 obj.SetValue(DisplayRowNumberProperty, value);
45 }
46
47 private static void OnDisplayRowNumberChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
48 {
49 DataGrid dataGrid = obj as DataGrid;
50 if ((bool)e.NewValue == true)
51 {
52 EventHandler<DataGridRowEventArgs> loadedRowHandler = null;
53 loadedRowHandler = (sender, ea) =>
54 {
55 if (GetDisplayRowNumber(dataGrid) == false)
56 {
57 dataGrid.LoadingRow -= loadedRowHandler;
58 return;
59 }
60 ea.Row.Header = ea.Row.GetIndex() + 1;
61 };
62 dataGrid.LoadingRow += loadedRowHandler;
63
64 ItemsChangedEventHandler itemsChangedHandler = null;
65 itemsChangedHandler = (sender, ea) =>
66 {
67 if (GetDisplayRowNumber(dataGrid) == false)
68 {
69 dataGrid.ItemContainerGenerator.ItemsChanged -= itemsChangedHandler;
70 return;
71 }
72 GetVisualChildCollection<DataGridRow>(dataGrid).
73 ForEach(d => d.Header = d.GetIndex() + 1);
74 };
75 dataGrid.ItemContainerGenerator.ItemsChanged += itemsChangedHandler;
76 }
77 }
78
79 #endregion // DisplayRowNumber
80
81 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
82
83 #region ObserveSelectedItem
84
88 public static readonly DependencyProperty ObserveSelectedItemProperty =
89 DependencyProperty.RegisterAttached("ObserveSelectedItem",
90 typeof(object),
91 typeof(DataGridBehavior),
92 new PropertyMetadata(null, OnObserveSelectedItemChanged));
93
99 public static object GetObserveSelectedItem(DependencyObject obj)
100 => obj.GetValue(ObserveSelectedItemProperty);
101
107 public static void SetObserveSelectedItem(DependencyObject obj, object value)
108 => obj.SetValue(ObserveSelectedItemProperty, value);
109
110 private static void OnObserveSelectedItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
111 {
112 if (d is DataGrid dataGrid && e.NewValue != null)
113 {
114 DependencyPropertyDescriptor descriptor = DependencyPropertyDescriptor.FromProperty(ObserveSelectedItemProperty, typeof(DataGrid));
115 descriptor?.AddValueChanged(d, (sender, args) =>
116 {
117 DataGrid dg = (DataGrid)sender;
118 object selectedItem = GetObserveSelectedItem(dg);
119 if (selectedItem != null)
120 {
121 dg.Dispatcher.InvokeAsync(() =>
122 {
123 dg.ScrollIntoView(selectedItem);
124 });
125 }
126 });
127 }
128 }
129
130 #endregion
131
132 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
133
134 #region ThreeStateSort
135
139 public static readonly DependencyProperty EnableThreeStateSortingProperty =
140 DependencyProperty.RegisterAttached("EnableThreeStateSorting",
141 typeof(bool),
142 typeof(DataGridBehavior),
143 new PropertyMetadata(false, OnEnableThreeStateSortingChanged));
144
150 public static bool GetEnableThreeStateSorting(DependencyObject obj)
151 => (bool)obj.GetValue(EnableThreeStateSortingProperty);
152
158 public static void SetEnableThreeStateSorting(DependencyObject obj, bool value)
159 => obj.SetValue(EnableThreeStateSortingProperty, value);
160
161 private static void OnEnableThreeStateSortingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
162 {
163 if (d is not DataGrid dataGrid)
164 return;
165
166 if ((bool)e.NewValue)
167 dataGrid.Sorting += OnDataGridSorting;
168 else
169 dataGrid.Sorting -= OnDataGridSorting;
170 }
171
172 // Code was generated with the help of ChatGPT
173 private static void OnDataGridSorting(object sender, DataGridSortingEventArgs e)
174 {
175 DataGrid grid = (DataGrid)sender;
176 string path = e.Column.SortMemberPath;
177 if (string.IsNullOrEmpty(path)) { return; }
178
179 bool shiftPressed = Keyboard.Modifiers.HasFlag(ModifierKeys.Shift);
180 e.Handled = true;
181
182 // Get the new sort direction based on the current sort direction
183 ListSortDirection? newDirection = e.Column.SortDirection switch
184 {
185 null => ListSortDirection.Ascending,
186 ListSortDirection.Ascending => ListSortDirection.Descending,
187 ListSortDirection.Descending => null,
188 _ => null
189 };
190
191 // If Shift is NOT pressed → clear all previous sortings
192 if (!shiftPressed)
193 {
194 foreach (DataGridColumn c in grid.Columns)
195 {
196 if (!ReferenceEquals(c, e.Column))
197 {
198 c.SortDirection = null;
199 }
200 }
201 grid.Items.SortDescriptions.Clear();
202 }
203
204 // Remove the column from SortDescriptions if it exists
205 SortDescription existingSortDescription = grid.Items.SortDescriptions.FirstOrDefault(sd => sd.PropertyName == path);
206 if (!string.IsNullOrEmpty(existingSortDescription.PropertyName))
207 {
208 grid.Items.SortDescriptions.Remove(existingSortDescription);
209 }
210
211 if (newDirection != null)
212 {
213 // Add new SortDescription with the new direction
214 grid.Items.SortDescriptions.Add(new SortDescription(path, newDirection.Value));
215 e.Column.SortDirection = newDirection;
216 }
217 else
218 {
219 // No sorting → reset column
220 e.Column.SortDirection = null;
221 }
222
223 // Apply sorting
224 grid.Items.Refresh();
225 }
226
227 #endregion
228
229 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
230
231 #region Get Visuals
232
233 private static List<T> GetVisualChildCollection<T>(object parent) where T : Visual
234 {
235 List<T> visualCollection = new List<T>();
236 GetVisualChildCollection(parent as DependencyObject, visualCollection);
237 return visualCollection;
238 }
239
240 private static void GetVisualChildCollection<T>(DependencyObject parent, List<T> visualCollection) where T : Visual
241 {
242 int count = VisualTreeHelper.GetChildrenCount(parent);
243 for (int i = 0; i < count; i++)
244 {
245 DependencyObject child = VisualTreeHelper.GetChild(parent, i);
246 if (child is T)
247 {
248 visualCollection.Add(child as T);
249 }
250 if (child != null)
251 {
252 GetVisualChildCollection(child, visualCollection);
253 }
254 }
255 }
256
257 #endregion // Get Visuals
258
259 }
260}
Behavior to display row numbers in the DataGrid row headers and scroll to the selected item in the Da...
static DependencyProperty DisplayRowNumberProperty
Attached property to enable displaying row numbers (1-based) in the DataGrid row headers.
static readonly DependencyProperty EnableThreeStateSortingProperty
Attached property to enable three state sorting (Ascending, Descending, Disabled) and MultiColumn sor...
static bool GetEnableThreeStateSorting(DependencyObject obj)
Gets the value of the EnableThreeStateSorting attached property from a DependencyObject.
static void SetEnableThreeStateSorting(DependencyObject obj, bool value)
Sets the value of the EnableThreeStateSorting attached property on a DependencyObject.
static readonly DependencyProperty ObserveSelectedItemProperty
Attached property to observe the selected item in a DataGrid and scroll to it when it changes.
static object GetObserveSelectedItem(DependencyObject obj)
Gets the value of the ObserveSelectedItem attached property from a DependencyObject.
static void SetObserveSelectedItem(DependencyObject obj, object value)
Sets the value of the ObserveSelectedItem attached property on a DependencyObject.
static void SetDisplayRowNumber(DependencyObject obj, bool value)
Sets the value of the DisplayRowNumber attached property on a DependencyObject.
static bool GetDisplayRowNumber(DependencyObject obj)
Get the value of the DisplayRowNumber attached property from a DependencyObject.