Простой способ отображения номеров строк в WPF DataGrid - PullRequest
23 голосов
/ 11 января 2011

Я просто хочу отобразить номера строк в крайнем левом столбце моего DataGrid.Есть какой-нибудь атрибут для этого?

Имейте в виду, это не первичный ключ для моей таблицы.Я не хочу, чтобы эти номера строк перемещались вместе со своими строками при сортировке столбца.Я в основном хочу подсчет.Для этого даже не нужно иметь заголовок.

Ответы [ 8 ]

34 голосов
/ 12 января 2011

Один из способов - добавить их в событие LoadingRow для DataGrid

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

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

Когда элементы добавляются или удаляются из списка источников, числа могут на некоторое время не синхронизироваться.Чтобы исправить это, см. Прикрепленное поведение здесь:
WPF 4 DataGrid: получение номера строки в RowHeader

Может использоваться следующим образом

<DataGrid ItemsSource="{Binding ...}"
          behaviors:DataGridBehavior.DisplayRowNumber="True"> 
9 голосов
/ 21 ноября 2013

Добавление краткой информации об ответе Фредрика Хедблада.

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

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

... Если вы хотите начать нумерацию с 1

7 голосов
/ 15 ноября 2016

Если ваша сетка данных имеет свой ItemsSource, связанный с коллекцией, свяжите свойство AlternationCount вашей сетки данных со свойством count вашей коллекции или со свойством Items.Count вашей DataGrid следующим образом:

<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 голосов
/ 24 апреля 2015

И просто, чтобы добавить к обсуждению этого ... (я потратил слишком много времени, чтобы выяснить это!).

Вам нужно установить значение EnableRowVirtualization в False на сетке данных, чтобы предотвратить ошибки впоследовательность строк:

EnableRowVirtualization="False"

По умолчанию для свойства EnableRowVirtualization установлено значение true.Когда для свойства EnableRowVirtualization установлено значение true, DataGrid не создает объект DataGridRow для каждого элемента данных в связанном источнике данных.Вместо этого DataGrid создает объекты DataGridRow только тогда, когда они необходимы, и использует их столько, сколько может. MSDN Ссылка здесь

3 голосов
/ 06 января 2016

Это старый вопрос, но я хотел бы поделиться чем-то. У меня была похожая проблема, все, что мне было нужно, это простая RowHeader нумерация строк, и ответ Фредрика Хедблада был почти полным для моей задачи.

Пока это здорово:

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

2 голосов
/ 22 февраля 2017

Просто еще один ответ, предоставляющий пример копирования и вставки (не поощряемый) для новых людей или спешащих людей, вдохновленных ответами в этом посте @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), как было предупреждено в Фредрик Хедблад, ответьте в Проверке, является ли строка нечетным числом

enter image description here

0 голосов
/ 11 апреля 2019

После некоторых испытаний с 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>
0 голосов
/ 03 июля 2015

Используя вложенные свойства, полный исходный код здесь .

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