在WPF DataGrid上显示行号的简单方法

问题描述 投票:22回答:8

我只想在DataGrid最左边的列中显示行号。这有什么属性吗?

请记住,这不是我桌子的主键。当列排序时,我不希望这些行号与它们的行一起移动。我基本上想要一个运行计数。它甚至不需要标题。

c# wpf wpfdatagrid
8个回答
34
投票

一种方法是在DataGrid的LoadingRow事件中添加它们

<DataGrid Name="DataGrid" LoadingRow="DataGrid_LoadingRow" ...

void DataGrid_LoadingRow(object sender, DataGridRowEventArgs e)
{
    e.Row.Header = (e.Row.GetIndex()).ToString(); 
}

在源列表中添加或删除项目时,这些数字可能会暂时不同步。有关此问题的修复,请参阅此处附加的行为: WPF 4 DataGrid: Getting the Row Number into the RowHeader

可以这样使用

<DataGrid ItemsSource="{Binding ...}"
          behaviors:DataGridBehavior.DisplayRowNumber="True"> 

9
投票

添加关于Fredrik Hedblad答案的简短信息。

<DataGrid Name="DataGrid" LoadingRow="DataGrid_LoadingRow" ...

void DataGrid_LoadingRow(object sender, DataGridRowEventArgs e)
{
    e.Row.Header = (e.Row.GetIndex()+1).ToString(); 
}

...如果你想从1开始编号


7
投票

如果您的数据网格将其ItemsSource绑定到集合,请将数据网格的AlternationCount属性绑定到集合的count属性,或绑定到DataGrid的Items.Count属性,如下所示:

<DataGrid ItemsSource="{Binding MyObservableCollection}" AlternationCount="{Binding MyObservableCollection.Count}" />

要么:

<DataGrid ItemsSource="{Binding MyObservableCollection}" AlternationCount="{Binding Items.Count, RelativeSource={RelativeSource Self}" />

要么应该工作。

然后,假设您在最左侧的列中使用DataGridTextColumn,则在DataGrid.Columns定义中执行以下操作:

<DataGrid.Columns>
   <DataGridTextColumn Binding="{Binding AlternationIndex, RelativeSource={RelativeSource AncestorType=DataGridRow}}"
</DataGrid.Columns>

如果您不想从0开始,可以在绑定中添加转换器以增加索引。


4
投票

而且只是为了加入对此的讨论......(我花了太多时间发现它!)。

您需要在datagrid上将EnableRowVirtualization设置为False以防止行排序中的错误:

EnableRowVirtualization="False"

EnableRowVirtualization属性默认设置为true。当EnableRowVirtualization属性设置为true时,DataGrid不会为绑定数据源中的每个数据项实例化DataGridRow对象。相反,DataGrid仅在需要时才创建DataGridRow对象,并尽可能多地重用它们。 MSDN Reference here


3
投票

这是一个老问题,但我想分享一些东西。我有一个类似的问题,我需要的是一个简单的RowHeader行数和Fredrik Hedblad的答案几乎完成我的问题。

虽然这很棒:

<DataGrid Name="DataGrid" LoadingRow="DataGrid_LoadingRow" ...

void DataGrid_LoadingRow(object sender, DataGridRowEventArgs e)
{
    e.Row.Header = (e.Row.GetIndex()).ToString(); 
}

删除和添加项目时,我的标题搞砸了。如果您有按钮负责,只需在“删除”代码下添加dataGrid.Items.Refresh();,如我的情况:

private void removeButton_Click(object sender, RoutedEventArgs e)
{
    // delete items

    dataGrid.Items.Refresh();
}

这解决了我的失步计算,因为刷新的项目再次调用qazxsw poi。


2
投票

另一个答案是为新人或匆忙中的人提供几乎复制和粘贴的例子(不被鼓励),灵感来自@GrantA和@Johan Larsson(以及许多其他回答了该主题的众多帖子的人)的回答)

  • 您可能不希望在列中添加枚举
  • 您无需重新创建自己的附加属性 DataGrig_LoadingRow

请注意<UserControl... <Grid> <DataGrid ItemsSource="{Binding MainData.ProjColl}" AutoGenerateColumns="False" AlternationCount="{ Binding MainData.ProjColl.Count}" > <DataGrid.Columns> <!--Columns given here for example--> ... <DataGridTextColumn Header="Project Name" Binding="{Binding CMProjectItemDirName}" IsReadOnly="True"/> ... <DataGridTextColumn Header="Sources Dir" Binding="{Binding CMSourceDir.DirStr}"/> ... </DataGrid.Columns> <!--The problem of the day--> <DataGrid.RowHeaderStyle> <Style TargetType="{x:Type DataGridRowHeader}"> <Setter Property="Content" Value="{Binding Path=(ItemsControl.AlternationIndex), RelativeSource={RelativeSource AncestorType=DataGridRow}}"/> </Style> </DataGrid.RowHeaderStyle> </DataGrid> </Grid> </UserControl> 中警告的(ItemsControl.AlternationIndex)周围的括号()

Fredrik Hedblad answer in Check if Row as odd number


0
投票

使用附加属性,完整源enter image description here

here

XAML:

using System.Windows;
using System.Windows.Controls;

public static class Index
{
    private static readonly DependencyPropertyKey OfPropertyKey = DependencyProperty.RegisterAttachedReadOnly(
        "Of",
        typeof(int),
        typeof(Index),
        new PropertyMetadata(-1));

    public static readonly DependencyProperty OfProperty = OfPropertyKey.DependencyProperty;

    public static readonly DependencyProperty InProperty = DependencyProperty.RegisterAttached(
        "In",
        typeof(DataGrid),
        typeof(Index),
        new PropertyMetadata(default(DataGrid), OnInChanged));

    public static void SetOf(this DataGridRow element, int value)
    {
        element.SetValue(OfPropertyKey, value);
    }

    public static int GetOf(this DataGridRow element)
    {
        return (int)element.GetValue(OfProperty);
    }

    public static void SetIn(this DataGridRow element, DataGrid value)
    {
        element.SetValue(InProperty, value);
    }

    public static DataGrid GetIn(this DataGridRow element)
    {
        return (DataGrid)element.GetValue(InProperty);
    }

    private static void OnInChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var row = (DataGridRow)d;
        row.SetOf(row.GetIndex());
    }
}

0
投票

经过<DataGrid ItemsSource="{Binding Data}"> <DataGrid.RowStyle> <Style TargetType="{x:Type DataGridRow}"> <Setter Property="dataGrid2D:Index.In" Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" /> </Style> </DataGrid.RowStyle> <DataGrid.RowHeaderStyle> <Style TargetType="{x:Type DataGridRowHeader}"> <Setter Property="Content" Value="{Binding Path=(dataGrid2D:Index.Of), RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}}" /> </Style> </DataGrid.RowHeaderStyle> </DataGrid> 的一些测试后,来自NGI的修复和扩展样本:

RowHeaderStyle
© www.soinside.com 2019 - 2024. All rights reserved.