web-dev-qa-db-ja.com

WPF DataGridに行番号を表示する簡単な方法

DataGridの左端の列に行番号を表示したいだけです。これを行うための属性はありますか?

これは私のテーブルの主キーではないことに注意してください。列を並べ替えるときに、これらの行番号が行とともに移動しないようにします。基本的にランニングカウントが欲しいです。ヘッダーさえ必要ありません。

24
JohnB

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:RowHeaderへの行番号の取得

このように使用可能

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

Fredrik Hedbladの回答に関する短い情報を追加します。

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

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

... 1から番号付けを開始する場合

9
JohnnyJaxs

データグリッドの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から始めたくない場合は、バインディングにコンバーターを追加してインデックスをインクリメントできます。

8
GrantA

そして、これに関する議論に追加するために...(私はこれを見つけるのに時間がかかりすぎました!)。

行順序付けのエラーを防ぐために、データグリッドでEnableRowVirtualizationをFalseに設定する必要があります。

EnableRowVirtualization="False"

EnableRowVirtualizationプロパティは、デフォルトでtrueに設定されます。 EnableRowVirtualizationプロパティがtrueに設定されている場合、DataGridはバインドされたデータソースの各データ項目のDataGridRowオブジェクトをインスタンス化しません。代わりに、DataGridは必要な場合にのみDataGridRowオブジェクトを作成し、可能な限り再利用します。 MSDNリファレンスはこちら

4
P_Fitz

古い質問ですが、何か共有したいと思います。同様の問題がありました。必要なのは単純な行の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_が呼び出されるため、これで非同期化された数値が解決されました。

3
trollsteen

@GrantAと@Johan Larssonによるこの投稿内の回答に触発された、新しい人やRushの人向けのコピー&ペーストの例(推奨されません)を提供するもう1つの回答)

  • 列内に列挙を追加したくない場合があります
  • 独自の添付プロパティを再作成する必要はありません

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

奇数行として行をチェックするでのFredrik Hedbladの回答 で警告された(ItemsControl.AlternationIndex)の周りの括弧()に注意

enter image description here

2
NGI

添付プロパティを使用して、完全なソース こちら

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>
0
Johan Larsson

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
omei