22

I am trying to implement a very simple spreadsheet functionality based on a DataGrid.

  1. The user clicks on a cell

  2. The user types a value and presses return

  3. The current row is scanned and any cell formula that depends on the clicked cell is updated.

This seems to be the best event handler for my requirements:

private void my_dataGrid_CurrentCellChanged(object sender, EventArgs e)

Question: How do I detect the row index of the current row?

Rekshino
  • 6,954
  • 2
  • 19
  • 44
Travis Banger
  • 697
  • 1
  • 7
  • 19
  • 1
    information about the object causing CurrentCellChanged event to be fired usually available in the EventArgs e. Try to put breakpoint and inspect what information 'e' brings for you. – har07 Nov 24 '13 at 01:32
  • Nothing as eventargs is the base class and not derived :) – BRAHIM Kamel Nov 24 '13 at 01:33

5 Answers5

45

Try this (assuming the name of your grid is "my_dataGrid"):

var currentRowIndex = my_dataGrid.Items.IndexOf(my_dataGrid.CurrentItem);

Normally, you'd be able to use my_dataGrid.SelectedIndex, but it seems that with the CurrentCellChanged event, the value of SelectedIndex always displays the previously selected index. This particular event seems to fire before the value of SelectedIndex actually changes.

Grant Winney
  • 65,241
  • 13
  • 115
  • 165
5

The accepted solution will work until you have no reference-duplicates in the ItemsSource, otherwise you will get index of the object's first occurrence.

The solution from BRAHIM Kamel will work until you have a selection, otherwise(if you click twice and deselect a cell/row) you will not have a SelectedIndex.

With YourDataGrid.ItemContainerGenerator.ContainerFromItem( _dataItemFromCurentCell ) as DataGridRow you will get by duplicates always the last occurrence of data item.

I would handle DataGrid.PreviewMouseLeftButtonDown event and search in handler the visual tree up to a DatagridRow, which has DatagridRow.GetIndex() method. So you will get always the right row index.

<DataGrid ... PreviewMouseLeftButtonDown="Previe_Mouse_LBtnDown" >
    ...
</DataGrid>

private void Previe_Mouse_LBtnDown(object sender, MouseButtonEventArgs e)
{
    DataGridRow dgr = null;
    var visParent = VisualTreeHelper.GetParent(e.OriginalSource as FrameworkElement);
    while (dgr == null && visParent != null)
    {
        dgr = visParent as DataGridRow;
        visParent = VisualTreeHelper.GetParent(visParent);
    }
    if (dgr == null) { return; }

    var rowIdx=dgr.GetIndex();
}
Rekshino
  • 6,954
  • 2
  • 19
  • 44
4

Hi you can do something like this to do your spreadsheed

 //not recomended  as it always  return the previous index of the selected row 
 void dg1_CurrentCellChanged(object sender, EventArgs e)
    {

       int rowIndex = dg1.SelectedIndex;   
     }

but if you want a more elaborated example this is how you can do it

namespace WpfApplication2
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    ObservableCollection<Tuple<string,string>> observableCollection = new ObservableCollection<Tuple<string,string>>();  
    public MainWindow()
    {
        InitializeComponent();            
        for (int i = 0; i < 100; i++)
        {
            observableCollection.Add( Tuple.Create("item " + i.ToString(),"=sum (c5+c4)"));
        }

        dg1.ItemsSource = observableCollection; 

        dg1.CurrentCellChanged += dg1_CurrentCellChanged;

    }

    void dg1_CurrentCellChanged(object sender, EventArgs e)
    {
        //int rowIndex = dg1.SelectedIndex;   
        Tuple<string, string> tuple = dg1.CurrentItem as Tuple<string, string>; 
        //here as you have your datacontext you can loop through and calculate what you want 

    }
}
}

Hope this help

Rekshino
  • 6,954
  • 2
  • 19
  • 44
BRAHIM Kamel
  • 13,492
  • 1
  • 36
  • 47
2

1.When click on the Cell inside the Datagrid, Get the CurrentCell info

2.From the DatagridCellInfo, we can find Column and Row index of particular cell

private void CellClick(object sender,RoutedEventArgs e)
    {
     DataGridCellInfo cell=DataGrid.CurrentCell;
     int columnindex=cell.Column.DisplayIndex;
     int rowIndex=DataGrid.Items.IndexOf(cell.Item);
    }
  • 6
    When answering an old question, your answer would be much more useful to other StackOverflow users if you included some context to explain how your answer helps, particularly for a question that already has an accepted answer. See: [How do I write a good answer](https://stackoverflow.com/help/how-to-answer). – David Buck Dec 19 '19 at 08:17
  • 1
    @DavidBuck not only for an answer to old questions :) – Maximilian Ast Dec 19 '19 at 09:33
-2
GRD.Items.Count;
DataGridRow row = (DataGridRow) GRD.ItemContainerGenerator.ContainerFromIndex(i);     
DataGridCell TXTGROUPID = GRD.Columns[2].GetCellContent(row).Parent as DataGridCell;               
string str = ((TextBlock) TXTGROUPID.Content).Text;
MessageBox.Show(str);
parakmiakos
  • 2,994
  • 9
  • 29
  • 43
Anand
  • 11