2017-02-18 23 views
0

私はさまざまなことを試みましたが、データグリッドの左側に行カウンタを追加する方法を知りたいのですが?WPFデータグリッド、どのように "左側の"ヘッダーを作成するには?

(私たちは、Excelで見られるような)私はその可能性を参照してください。

enter image description here

を私はこれを達成する方法を知ってはいけません。

私はWPFの場合はnewbですが、オブジェクトのプロパティにはそれをアクティブにする "チェックボックス"がないことを認めていますが、これまで明示的なコードはありませんでした。その単純な、またはいくつかの精巧なハック場合。

TY。

+0

まあそれは簡単ではありませんが、それはどちらか正確にハックではありません。それは多かれ少なかれカスタムコントロールを作る必要があります。私はあなたがWPFでより強力な立場を持つまで、心配する必要はないと思います。 (ちょうど最近winformsからWPFに切り替えた人として話す)。 –

+0

ありがとうございます。私はWPFの基本について作業します。私は自分のカスタムコントロールを作る代わりに、これを "チェックボックス"のものにすることを望んでいました。 –

答えて

1

次のリンクで、この利用可能を行う方法で利用できる完全なコードサンプルがあります。

は、WPFでDataGridRowHeaderに右揃え行番号を追加:https://blog.magnusmontin.net/2014/08/18/right-aligned-row-numbers-datagridrowheader-wpf/

あなたはDataGridRowHeaderTemplateTextBlockを入れて、行のインデックスを取得するには、コンバータを使用することができます。

<DataGrid ItemsSource="{Binding Countries}" AutoGenerateColumns="False" 
    xmlns:local="clr-namespace:Mm.WpfApplication1"> 
    <DataGrid.Columns> 
     <DataGridTextColumn Header="Country" Binding="{Binding Name}"/> 
    </DataGrid.Columns> 
    <DataGrid.Resources> 
     <local:RowNumberConverter x:Key="converter"/> 
    </DataGrid.Resources> 
    <DataGrid.RowHeaderTemplate> 
     <DataTemplate> 
      <TextBlock Text="{Binding Path=., 
         RelativeSource={RelativeSource AncestorType=DataGridRow}, 
         Converter={StaticResource converter}}"></TextBlock> 
     </DataTemplate> 
    </DataGrid.RowHeaderTemplate> 
    <DataGrid.RowHeaderStyle> 
     ... 
    </DataGrid.RowHeaderStyle> 
</DataGrid> 

しかし、このアプローチは、だけにして、仮想化が無効になっているか、あなたのItemsSourceに数行しか持っていたときに動作します。行番号を正しく表示したいが、DataGridのデフォルトの仮想化とリサイクルの動作を維持する場合はDataGridLoadingRowイベントを処理して、DataGridRowHeaderプロパティを行番号に設定してから、このプロパティにバインドします。 RowHeaderTemplate

DataGridObservableCollection<T>にバインドされ、あなたがに項目を追加または削除されている/それから、実行時に動的にあれば、行番号を使用すると、スクロールを開始するまで更新されず、LoadingRowイベントが再び発射されることに注意してください。

これを修正するには、ビュー内のDataGridItemContainerGeneratorItemsChangedイベントにイベントハンドラをフックアップし、このイベントが発生したときに、ビジュアルツリー内に現在あるすべてのDataGridRow要素のHeaderプロパティをリセットできます。

は、より多くの情報と、完全な作業のサンプルについては、上記のリンクを参照してください。

+0

それは素晴らしいです。 –

1

メインウィンドウ

public MainWindow() 
    { 
     InitializeComponent(); 
        DataTable tab = new DataTable(); 
     for (int i = 0; i < 10; i++) 
      tab.Columns.Add("col " + i.ToString()); 
     for (int i = 0; i < 1000; i++) 
     { 
      DataRow r = tab.NewRow(); 
      for (int j = 0; j < 10; j++) 
       r[j] = "row " + (i).ToString() + "-col " + (j).ToString(); 
      tab.Rows.Add(r); 
     } 
     dg.ItemsSource = tab.AsDataView(); 
    } 

XAMLを使用し、その後、データグリッドを埋めるとしたDataTableを使用し

<Window.Resources> 
    <local:HeaderConverter x:Key="headerConverter"/> 
</Window.Resources> 

<Grid> 
    <DataGrid Name="dg"> 
     <DataGrid.RowHeaderTemplate> 
      <DataTemplate> 
       <TextBlock MinWidth="30" TextAlignment="Center"> 
        <TextBlock.Text> 
         <MultiBinding Converter="{StaticResource headerConverter}"> 
          <Binding Path="ItemsSource" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=DataGrid}" /> 
          <Binding Path="Item" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=DataGridRow}"/> 
         </MultiBinding> 
        </TextBlock.Text> 
       </TextBlock> 
      </DataTemplate> 
     </DataGrid.RowHeaderTemplate> 
    </DataGrid> 
</Grid> 

コンバータ

public class HeaderConverter : IMultiValueConverter 
{ 
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 
    { 
     int ind = -1; 
     DataView dv = values[0] as DataView; 
     if (dv != null) 
     { 
      DataRowView drv = values[1] as DataRowView; 
      ind = dv.Table.Rows.IndexOf(drv.Row); 
     } 
     else 
     { 
      System.Collections.IEnumerable ien = values[0] as System.Collections.IEnumerable; 
      ind = IndexOf(ien, values[1]); 
     } 
     if (ind == -1) 
      return ""; 
     else 
      return (ind + 1).ToString(); 
    } 
    static int IndexOf(System.Collections.IEnumerable source, object value) 
    { 
     int index = 0; 
     foreach (var item in source) 
     { 
      if (item.Equals(value)) 
       return index; 
      index++; 
     } 
     return -1; 
    } 

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 
+0

'RowHeaderTemplate'はこれを行う正しい方法ですが、DataGridが[* CollectionViewSource *](https://msdn.microsoft.com/en-us/library/ff407126)にバインドされていると、行番号付けが機能しませんv = vs.110).aspx) – slugster

+0

ありがとうございました。それは簡単な例でしたが、私は答えを更新しました。 – Ron

+0

@ Luca Deskovic:Converterの "IEnumerable"部分もDataTableを処理できますが、インデックスをソートに保持しないことに注意してください。そういうわけで私はその部分をifで区切ります。 – Ron

関連する問題