【问题标题】:Simple way to display row numbers on WPF DataGrid在 WPF DataGrid 上显示行号的简单方法
【发布时间】:2011-06-07 09:56:38
【问题描述】:

我只想在DataGrid 的最左列显示行号。是否有一些属性可以做到这一点?

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

【问题讨论】:

标签: c# wpf wpfdatagrid


【解决方案1】:

一种方法是将它们添加到 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"> 

【讨论】:

  • 这会在排序过程中移动行号吗?还是在排序期间也调用了LoadingRow,这将使行号始终保持有序?
  • @VoodooChild:是的,我已经用过几次了,据我所知,行号总是按正确的顺序排列,即使是排序、滚动、更改 ItemsSource 等. 虽然,这里的一个人告诉我,这对他不起作用。我向他询问更多信息,但他从未回复。但对我来说,我从未见过失败的情况:)
  • 如果你想从#1开始:e.Row.Header = (e.Row.GetIndex() + 1).ToString();
  • 确保属性HeadersVisibility 设置为AllRowColumnsNone 不会显示。例如:&lt;DataGrid HeaderVisibility="All"&gt;&lt;/DataGrid&gt;
  • 这不适用于虚拟化。如何调整代码以使用虚拟行?
【解决方案2】:

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

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

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

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

【讨论】:

    【解决方案3】:

    如果您的数据网格将其 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 开始,你可以在你的绑定中添加一个转换器来增加索引。

    【讨论】:

    • 如果您在数据网格中滚动并重新加载您的收藏,这将无法正常工作。编号将从您在数据网格中滚动到的顶部的项目上的 0 开始。
    • 这对我有用但是当我使用鼠标在数据网格上滚动时索引号会随机变化如何解决这个问题??
    【解决方案4】:

    这是一个老问题,但我想分享一些东西。我有一个类似的问题,我只需要一个简单的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();
    }
    

    这为我解决了非同步计数问题,因为刷新项目再次调用DataGrig_LoadingRow

    【讨论】:

      【解决方案5】:

      只是为了补充关于这个的讨论......(我花了太多时间才发现这个!)。

      您需要在数据网格上将 EnableRowVirtualization 设置为 False 以防止行排序错误:

      EnableRowVirtualization="False"
      

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

      【讨论】:

      • 禁用虚拟化很糟糕......有没有办法让它与虚拟化一起工作?
      【解决方案6】:

      受@GrantA 和@Johan Larsson 的这篇文章中的答案启发(+许多其他人回答了许多帖子)关于那个主题)

      • 您可能不想在列中添加枚举
      • 您不需要重新创建自己的附加属性

        <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 中所警告的那样

      【讨论】:

        【解决方案7】:

        经过RowHeaderStyle的一些测试,来自NGI的修复和扩展样本:

                <DataGrid EnableRowVirtualization="false" ItemsSource="{Binding ResultView}" AlternationCount="{Binding ResultView.Count}" RowHeaderWidth="10">
                    <DataGrid.RowHeaderStyle>
                        <Style TargetType="{x:Type DataGridRowHeader}">
                            <Setter Property="Content" Value="{Binding Path=AlternationIndex, RelativeSource={RelativeSource AncestorType=DataGridRow}}" />
                        </Style>
                    </DataGrid.RowHeaderStyle>
                </DataGrid>
        

        【讨论】:

          【解决方案8】:

          使用附加属性,完整源代码here

          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());
              }
          }
          

          Xaml:

          <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>
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-03-18
            • 2013-02-10
            • 1970-01-01
            • 1970-01-01
            • 2020-12-15
            相关资源
            最近更新 更多