16 #region DisplayRowNumber
22 DependencyProperty.RegisterAttached(
"DisplayRowNumber",
25 new FrameworkPropertyMetadata(
false, OnDisplayRowNumberChanged));
47 private static void OnDisplayRowNumberChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
49 DataGrid dataGrid = obj as DataGrid;
50 if ((
bool)e.NewValue ==
true)
52 EventHandler<DataGridRowEventArgs> loadedRowHandler =
null;
53 loadedRowHandler = (sender, ea) =>
57 dataGrid.LoadingRow -= loadedRowHandler;
60 ea.Row.Header = ea.Row.GetIndex() + 1;
62 dataGrid.LoadingRow += loadedRowHandler;
64 ItemsChangedEventHandler itemsChangedHandler =
null;
65 itemsChangedHandler = (sender, ea) =>
69 dataGrid.ItemContainerGenerator.ItemsChanged -= itemsChangedHandler;
72 GetVisualChildCollection<DataGridRow>(dataGrid).
73 ForEach(d => d.Header = d.GetIndex() + 1);
75 dataGrid.ItemContainerGenerator.ItemsChanged += itemsChangedHandler;
83 #region ObserveSelectedItem
89 DependencyProperty.RegisterAttached(
"ObserveSelectedItem",
92 new PropertyMetadata(
null, OnObserveSelectedItemChanged));
110 private static void OnObserveSelectedItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
112 if (d is DataGrid dataGrid && e.NewValue !=
null)
114 DependencyPropertyDescriptor descriptor = DependencyPropertyDescriptor.FromProperty(
ObserveSelectedItemProperty, typeof(DataGrid));
115 descriptor?.AddValueChanged(d, (sender, args) =>
117 DataGrid dg = (DataGrid)sender;
119 if (selectedItem !=
null)
121 dg.Dispatcher.InvokeAsync(() =>
123 dg.ScrollIntoView(selectedItem);
134 #region ThreeStateSort
140 DependencyProperty.RegisterAttached(
"EnableThreeStateSorting",
143 new PropertyMetadata(
false, OnEnableThreeStateSortingChanged));
161 private static void OnEnableThreeStateSortingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
163 if (d is not DataGrid dataGrid)
166 if ((
bool)e.NewValue)
167 dataGrid.Sorting += OnDataGridSorting;
169 dataGrid.Sorting -= OnDataGridSorting;
173 private static void OnDataGridSorting(
object sender, DataGridSortingEventArgs e)
175 DataGrid grid = (DataGrid)sender;
176 string path = e.Column.SortMemberPath;
177 if (
string.IsNullOrEmpty(path)) {
return; }
179 bool shiftPressed = Keyboard.Modifiers.HasFlag(ModifierKeys.Shift);
183 ListSortDirection? newDirection = e.Column.SortDirection
switch
185 null => ListSortDirection.Ascending,
186 ListSortDirection.Ascending => ListSortDirection.Descending,
187 ListSortDirection.Descending =>
null,
194 foreach (DataGridColumn c
in grid.Columns)
196 if (!ReferenceEquals(c, e.Column))
198 c.SortDirection =
null;
201 grid.Items.SortDescriptions.Clear();
205 SortDescription existingSortDescription = grid.Items.SortDescriptions.FirstOrDefault(sd => sd.PropertyName == path);
206 if (!
string.IsNullOrEmpty(existingSortDescription.PropertyName))
208 grid.Items.SortDescriptions.Remove(existingSortDescription);
211 if (newDirection !=
null)
214 grid.Items.SortDescriptions.Add(
new SortDescription(path, newDirection.Value));
215 e.Column.SortDirection = newDirection;
220 e.Column.SortDirection =
null;
224 grid.Items.Refresh();
233 private static List<T> GetVisualChildCollection<T>(
object parent) where T : Visual
235 List<T> visualCollection =
new List<T>();
236 GetVisualChildCollection(parent as DependencyObject, visualCollection);
237 return visualCollection;
240 private static void GetVisualChildCollection<T>(DependencyObject parent, List<T> visualCollection) where T : Visual
242 int count = VisualTreeHelper.GetChildrenCount(parent);
243 for (
int i = 0; i < count; i++)
245 DependencyObject child = VisualTreeHelper.GetChild(parent, i);
248 visualCollection.Add(child as T);
252 GetVisualChildCollection(child, visualCollection);