Подтвердить что ты не робот

Простой способ отображения номеров строк в WPF DataGrid

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

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

4b9b3361

Ответ 1

Один из способов - добавить их в событие LoadRow для 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"> 

Ответ 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

Если ваша сетка данных имеет свой ItemSource, связанный с коллекцией, привяжите свойство 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

И просто добавить к дискуссии об этом... (я слишком долго искал это!).

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

EnableRowVirtualization="False"

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

Ответ 5

Это старый вопрос, но я хотел бы поделиться чем-то. У меня была аналогичная проблема, мне нужна была простая нумерация строк 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(); под кодом "delete", как в моем случае:

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

    dataGrid.Items.Refresh();
}

Это решило для меня нумеруемую нумерацию, потому что обновляемые элементы снова набирают DataGrig_LoadingRow.

Ответ 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, ответьте в поле "Проверить, не строит ли строка" как нечетное число

введите описание изображения здесь

Ответ 7

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

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>

Ответ 8

После некоторых тестов с 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>