Get RowIndex while View is filtered

Hi,

is was wondering how to get the selected row indices while the grid is filtered. I use this expression to get all selected rows:

 SelectedRowNumbers = SelectionController.SelectedRows.Select(x => x.RowIndex).ToList();

My goal is to restore the selection after reloading the data. It works fine as long as the Grid is not filtered. If it is filtered I get the row indices from a view perspective but SelectRows() seems to work on the datasource row indices.

I was looking for a helper function but GridIndexResolver.ResolveToRowIndex(...) returns only the View Row Index, nothing to feed SelectRows().

Any hints?

Regards
Bernd



5 Replies

GT Gnanasownthari Thirugnanam Syncfusion Team November 2, 2017 05:53 PM UTC

Hi Bernd, 

Based on your query we suspect that you had tried to get SelectedRows while filter applied in SfDataGrid. In SfDataGrid selection is cleared while filter is applied so you can get the SeletedRow from SfDataGrid.SelectedItems in FilterChanging event as like below code example. 

this.datagrid.FilterChanging += datagrid_FilterChanging; 
 
List<int> selectedIndex = new List<int>(); 
void datagrid_FilterChanging(object sender, GridFilterEventArgs e) 
{ 
    if (this.datagrid.SelectedItems.Count > 0) 
    { 
        foreach (var item in this.datagrid.SelectedItems) 
        { 
            //You can get the SelectedIndex here. 
            selectedIndex.Add(this.datagrid.ResolveToRowIndex(item as OrderInfo)); 
        } 
    } 
 

We have prepared the sample based on your  requirement , you can download it from below mentioned location. 

Sample link: 

Please let us know if you need further assistance on this. 

Regards, 
Gnanasownthari T. 
 



BE Bernd November 4, 2017 03:37 PM UTC

Hi Gnanasownthari,

thank you for the answer, unfortunately it does not address my problem. I am able to maintain the list of selected rows using SelectionController.SelectedRows.Select(x => x.RowIndex). This gives me the list of the selected rows based on the filtered view. Howver, SelectedRows() uses the provided parameters startRows and endRows ans selected based on the ItemsSource although the list is still filtered. Despite the question if it makes sens to reapply a filter after reloading data just based on row numbers this seems to be wrong. Let me describe an example:

There is a list

  1. a-1
  2. a-2
  3. b-1
  4. b-2
  5. b-3
This list is grouped by the first colum, so you see
  1. a (2 children)
  2. b (3 children)

I do now select row 1 and calculate the selected entries by accumulating all children, i.e. 2

Then I filter for column 1 = "b" My display is now:

  1. b (3 children)
My accumulated children count is still 3.

To maintain the selection a do SelectionController.SelectedRows.Select(x => x.RowIndex) which gives me row 1.

Then I do a refresh, the filter remains active. After that I reapply the selection by calling SelectRows(1, 1).

The problem no is, that SelectRows() seems to operate on the ItemsSource, thus selecting the filtered former row 1 with 3 children which is wrong.

I hope you got the idea. :-)

Best regards
Bernd Holz




GT Gnanasownthari Thirugnanam Syncfusion Team November 8, 2017 03:47 AM UTC

Hi Bernd, 
Based on your given details in last update, we suspect that you had tried the below mentioned steps in your application. 
  1. Group the first column. (a group having 2 children, b group having 3 children)
  2. Select the first group and get the selected index using SelectedRows in SelectionController.
  3. Now filter a group (display having b group alone)
  4. Now refresh the grid and reapply the selection using SelectRows method (based on previously SelectedIndex)
  5. Now b group is selected.
We have prepared the sample and video based on our suspicion. For your reference we have attached in below location. 
If your requirement is different from our suspicion could you please share more details about your requirement (like screenshot or video illustration) that will be helpful to provide appropriate solution at earliest. 
Note: Selection in SfDataGrid is proceed based on display items. 
Regards, 
Gnanasownthari T. 
 



BE Bernd November 20, 2017 10:05 AM UTC

Hi Gnanasownthari,

thank you for the provided sample. This is exactly the behaviour I encountered.

To you remark: Selection based on visible items makes perfect sense, the problem is that I did not find another way to remember the selection and reapply it after a refresh. If I had to implement it myself I would have to identify each row by an Id of the underlying object, which in fact I do not have right now. But maybe this is the way to go.

Regards
Bernd


GT Gnanasownthari Thirugnanam Syncfusion Team November 23, 2017 12:19 PM UTC

Hi Bernd, 

You can reapply the selection for CaptionsumarryRow and DataRow like below code example. 

C# 
//Maintain CaptionsummaryText 
List<object> captionSummaryRowText = new List<object>(); 
//Maintain the selected DataRowIndex 
List<int> dataRowIndex = new List<int>(); 
//Maintain SelectedIndex 
List<int> selectedIndex = new List<int>(); 
        
private void Button_Click(object sender, RoutedEventArgs e) 
{             
    selectedIndex = this.datagrid.SelectionController.SelectedRows.Select(x => x.RowIndex).ToList(); 
    foreach (int index in selectedIndex) 
    { 
        var captionSumaryRowControl = this.datagrid.RowGenerator.Items.Find(x => x.Index == index); 
        if (!(captionSumaryRowControl is DataRow)) 
        {               
            //Add the selected CaptionSumarryRow 
            var captionRowText = (captionSumaryRowControl.RowData as Group).Key; 
            captionSummaryRowText.Add(captionRowText); 
        } 
        else 
        { 
            //Add the selected DataRow  
            if (index <= this.datagrid.View.Records.Count) 
            { 
                var dataRow = this.datagrid.View.Records.ElementAt(index - 1).Data; 
                dataRowIndex.Add(viewModel.OrderInfoCollection.IndexOf(dataRow)); 
            }                  
        }               
    }          
} 
 
private void Button_Click1(object sender, RoutedEventArgs e) 
{ 
    var captionRows=this.datagrid.RowGenerator.Items.Where(x => x.RowType == RowType.CaptionCoveredRow); 
    var dataRows = this.datagrid.RowGenerator.Items.Where(x => x.RowType == RowType.DefaultRow); 
            
    foreach (int index in dataRowIndex) 
    { 
        if (index < viewModel.OrderInfoCollection.Count)  
        { 
            foreach (var dataRow in dataRows) 
            { 
                if (dataRow.RowData == viewModel.OrderInfoCollection.ElementAt(index)) 
                { 
                    //Reapply the selection for DataRow 
                    this.datagrid.SelectedItems.Add(dataRow.RowData); 
                    break; 
                } 
            } 
        } 
    } 
                 
    foreach (object captionRowText in captionSummaryRowText) 
    { 
        foreach (var captionRow in captionRows) 
        { 
            if (captionRowText.ToString() == (captionRow.RowData as Group).Key.ToString()) 
            { 
                //Reapply the selection for CaptionSumarryRow 
                       
                this.datagrid.SelectionController.SelectRows(captionRow.RowIndex, captionRow.RowIndex); 
                break; 
            }                  
        } 
    }           
}        

We have prepared the sample based on your requirement, you can download it from below mentioned location. 


Please let us know if you need further assistance on this. 

Regards, 
Gnanasownthari T. 
 


Loader.
Up arrow icon