WPF DataGrid sorszámok

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:

RowNumber

Hozzászólás