Mutatok egy újabb kis trükköt, amit pont most találtam ki. Mivel a DataGrid nem képes megjeleníteni a sorszámot, ráadásul a DataGridRow csak egy GetIndex() metódust tartalmaz ennek lekérdezésére, szükség van egy property-re. Ugye a DataGridRowHeader, és a DataGridCell is, mint gyermekei jelennek meg a DataGridRow-nak. Ez jó, ezt ki lehet használni. A DataGrid-nek pedig van egy LoadingRow eseménye. Semmi más dolgunk nincs, mint készíteni egy attached property-t, ami kiegészíti a DataGridRow–ot egy index tulajdonsággal (ami a DataGridRow.GetIndex()-ből veszi az értékét):
public sealed class DataGridRowExtender { public static int GetIndex(DataGridRow obj) { return (int)obj.GetValue(IndexProperty); } public static void SetIndex(DataGridRow obj, int value) { obj.SetValue(IndexProperty, value); } public static readonly DependencyProperty IndexProperty = DependencyProperty.RegisterAttached("Index", typeof(int),
typeof(DataGridRowExtender), new UIPropertyMetadata(
new PropertyChangedCallback(OnIndexChanged))); private static void OnIndexChanged( DependencyObject dpo, DependencyPropertyChangedEventArgs e) { var row = dpo as DataGridRow; if (row == null) return; var grid = UIHelper.GetParentByType<DataGrid>(row); if (grid == null) return; grid.LoadingRow -= OnLoaded; grid.LoadingRow += OnLoaded; } private static void OnLoaded(object sender, DataGridRowEventArgs e) { SetIndex(e.Row, e.Row.GetIndex() + 1); } }
Csiszoltam valamennyit ehhez az UIHelper osztályon is:
public sealed class UIHelper { public static T GetChildByType<T>(DependencyObject dpob) where T : DependencyObject { if (dpob == null) return null; var count = VisualTreeHelper.GetChildrenCount(dpob); for (var i = 0; i < count; i++) { var child = VisualTreeHelper.GetChild(dpob, i); T childAsT = child as T; if (childAsT != null) return childAsT; childAsT = GetChildByType<T>(child); if (childAsT != null) return childAsT; } return null; } public static T GetParentByType<T>(DependencyObject dpob) where T : DependencyObject { if (dpob == null) return null; var parent = dpob; while ((parent != null) && (parent is T == false)) parent = VisualTreeHelper.GetParent(parent); return parent as T; } }
Ezt követően pedig megadjuk az attached property-t a DataGridRow-on, illetve bekötjük azt a DataGridRowHeader ControlTemplate-jében található vezérlőkbe:
<!-- DataGridRow --> <Style TargetType="{x:Type basic:DataGridRow}"> <Setter Property="utils:DataGridRowExtender.Index" Value="-1"/> </Style>
<!-- DataGridRowHeader --> <Style TargetType="{x:Type primitives:DataGridRowHeader}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="primitives:DataGridRowHeader"> <CheckBox VerticalAlignment="Center" IsChecked="{Binding Path=IsSelected, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type basic:DataGridRow}}}" Content="{Binding Path=(utils:DataGridRowExtender.Index),
Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type basic:DataGridRow}}}"/> </ControlTemplate> </Setter.Value> </Setter> </Style>
Ha mindent jól csináltunk, az eredmény: