We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy.
Unfortunately, activation email could not send to your email. Please try again.

Very slow selection of rows in sfDataGrid

Thread ID:

Created:

Updated:

Platform:

Replies:

124337 Jun 1,2016 11:40 AM Jun 3,2016 09:26 AM WPF 3
loading
Tags: SfDataGrid
Andrey
Asked On June 1, 2016 11:40 AM

My current application is being designed to work with large datasets. Sometimes I have tens of thousands of rows in the datagrid. It all works great and fast with virtualization enabled, except for the row selection. When I select all rows to delete or process them, the grid freezes for a long time. In my latest measurement, when I tried selecting 64000  rows, it took 66000 milliseconds to do so, and I have a reasonably fast computer. (For reference, I need the same amount of time to delete these 64000 rows from 15 database tables using EF6, as well as purge any related binary files from disk.)

I believe sfDataGrid's selection implementation may be bugged or suboptimal, because the previous grid I was using before (DevExp) selected the same numbers of rows in a matter of milliseconds. So I would like to ask you to look into the implementation and produce a fix, if possible. Sadly, large selections are unusable at the monent.

This is the method I use for selecting rows:

sfDataGrid.SelectionController.ClearSelections(false); 
sfDataGrid.SelectRows(sfDataGrid.GetFirstDataRowIndex()sfDataGrid.GetLastDataRowIndex());


Jai Ganesh S [Syncfusion]
Replied On June 2, 2016 10:25 AM

Hi Andrey, 
You can improve the performance when you select the rows by customize the GridSelectionController and override the SelectRows method like below, 
this.datagrid.SelectionController = new GridSelectionControllerExt(datagrid); 
 
  public class GridSelectionControllerExt : GridSelectionController 
    { 
        SfDataGrid datagrid; 
        public GridSelectionControllerExt(SfDataGrid dataGrid) 
            : base(dataGrid) 
        { 
            datagrid = dataGrid; 
        } 
 
        public override void SelectRows(int startRowIndex, int endRowIndex) 
        { 
            if (startRowIndex < 0 || endRowIndex < 0) 
                return; 
 
            if (startRowIndex > endRowIndex) 
            { 
                var temp = startRowIndex; 
                startRowIndex = endRowIndex; 
                endRowIndex = temp; 
            } 
 
            if (this.DataGrid.SelectionMode == GridSelectionMode.None || 
                this.DataGrid.SelectionMode == GridSelectionMode.Single) 
                return; 
 
            var isSelectedRowsContains = this.SelectedRows.Any(); 
 
            this.SuspendUpdates(); 
            var addedItem = new List<object>(); 
            int rowIndex = startRowIndex; 
#if !WP 
                        ResetParentGridSelection(); 
#endif 
 
            var rowIndexes = this.GetRowIndexes(); 
 
            var selectedrowindex = this.datagrid.ResolveToRowIndex(this.datagrid.SelectedIndex); 
 
           // if (!this.DataGrid.GridModel.HasGroup) 
            { 
                int recordindex = 0; 
                GridRowInfo rowInfo = null; 
                for (int i = rowIndex; i <= endRowIndex; i++) 
                { 
                    object rowData = this.DataGrid.GetRecordAtRowIndex(rowIndex); 
                    rowIndex = this.DataGrid.ResolveToRowIndex(recordindex); 
                    if (!rowIndexes.Contains(rowIndex)) 
                    { 
                        this.DataGrid.SelectedItems.Add(rowData); 
                        this.SelectedRows.Add(GetGridSelectedRow(rowIndex)); 
                    } 
                    recordindex++; 
                } 
            } 
            this.ShowAllRowSelectionBorder(); 
            if (!isSelectedRowsContains) 
            { 
                this.RefreshSelectedIndex(); 
            } 
            this.ResumeUpdates(); 
        } 
        private void ResetParentGridSelection() 
        { 
            if (!(this.DataGrid is DetailsViewDataGrid)) 
                return; 
            var parentDataGrid = this.DataGrid.GetParentDataGrid(); 
            var selectionController = parentDataGrid.SelectionController as GridSelectionControllerExt; 
            var removedItems = selectionController.SelectedRows.ToList<object>(); 
            var rowIndex = parentDataGrid.GetGridDetailsViewRowIndex(this.DataGrid as DetailsViewDataGrid); 
            selectionController.ResetSelection(rowIndex, removedItems, true); 
             
        } 
 
        protected internal void ResetSelection(int rowIndex, List<object> removedItems, bool setFocuForGrid = true) 
        { 
            var addedItems = new List<object>(); 
            var rowInfo = this.GetGridSelectedRow(rowIndex); 
 
            if (!this.SelectedRows.Contains(rowInfo)) 
                addedItems.Add(rowInfo); 
 
           
            this.DataGrid.HideRowFocusBorder(); 
            if (removedItems != null && removedItems.Count > 0) 
            { 
                this.RemoveSelection(rowIndex, removedItems, SelectionReason.GridOperations); 
            } 
 
            if (addedItems.Count > 0) 
                this.AddSelection(addedItems, SelectionReason.GridOperations); 
 
        } 
 
 
        private void RefreshSelectedIndex() 
        { 
            this.DataGrid.SelectedIndex = this.SelectedRows.Count > 0 ? this.DataGrid.ResolveToRecordIndex(this.SelectedRows[0].RowIndex) : -1; 
            this.DataGrid.SelectedItem = this.DataGrid.SelectedItems.Count > 0 ? this.DataGrid.SelectedItems[0] : null; 
        } 
        internal List<int> GetRowIndexes() 
        { 
            return this.datagrid.SelectionController.SelectedRows.Select(rowinfo => rowinfo.RowIndex).ToList(); 
        } 
        
    } 
 
Sample: 
Regards, 
Jai Ganesh S 


Andrey
Replied On June 2, 2016 03:19 PM

Jai Ganesh S,

thank you for the suggested solution. I was able to reduce the selection time of 100,000 rows from 100,000ms to 100ms, i.e. it is now faster by a thousand times. I commented out lines that add rowData objects to DataGrid.SelectedItems. Now I can access the data items using this logic: var selectedItems = sfDataGrid.SelectionController.SelectedRows.Select(x => x.RowData as MyPocoClass).Select(x => x.Id); It is way better for speed and memory.

I still have the problem of slow selection when selecting by SHIFT-clicking on the first and last grid rows. It seems to use another method than the overridden SelectRows. Please advise on how I can fix the Shift-click selection as well. Thank you!


 public override void SelectRows(int startRowIndex, int endRowIndex)
        {
                if (startRowIndex < 0 || endRowIndex < 0)
                return;

            if (startRowIndex > endRowIndex)
            {
                var temp = startRowIndex;
                startRowIndex = endRowIndex;
                endRowIndex = temp;
            }

            if (this.DataGrid.SelectionMode == GridSelectionMode.None ||
                this.DataGrid.SelectionMode == GridSelectionMode.Single)
                return;

            var isSelectedRowsContains = this.SelectedRows.Any();

            this.SuspendUpdates();
           
        //    var addedItem = new List<object>();
            int rowIndex = startRowIndex;

           // ResetParentGridSelection();

            var rowIndexes = this.GetSelectedRowIndexes();

            //      var selectedrowindex = this.DataGrid.ResolveToRowIndex(this.DataGrid.SelectedIndex);

            // if (!this.DataGrid.GridModel.HasGroup)
           //{
                int recordindex = 0;
                //    GridRowInfo rowInfo = null;
                for (int i = rowIndex; i <= endRowIndex; i++)
                {
                    //object rowData = this.DataGrid.GetRecordAtRowIndex(rowIndex);                <= This is problematic
                    rowIndex = this.DataGrid.ResolveToRowIndex(recordindex);
                    if (!rowIndexes.Contains(rowIndex))
                    {
                        //this.DataGrid.SelectedItems.Add(rowData );                                           <= This is problematic
                        this.SelectedRows.Add(GetGridSelectedRow(rowIndex));
                    }
                    recordindex++;
                }
           // }

            this.ShowAllRowSelectionBorder();
            if (!isSelectedRowsContains)
            {
                this.RefreshSelectedIndex();
            }
            this.ResumeUpdates();
          
        }

Jai Ganesh S [Syncfusion]
Replied On June 3, 2016 09:26 AM

Hi Andrey, 
 
You can achieve your requirement to improve the performance when you shift selecting the first and last grid rows by overriding the ProcessPoinerReleased event like below, 
 
   protected override void ProcessPointerReleased(MouseButtonEventArgs args, Syncfusion.UI.Xaml.ScrollAxis.RowColumnIndex rowColumnIndex) 
        { 
            if (SelectionHelper.CheckShiftKeyPressed()) 
            { 
                this.SelectRows(this.PressedRowColumnIndex.RowIndex, rowColumnIndex.RowIndex); 
            } 
 
            else 
                base.ProcessPointerReleased(args, rowColumnIndex); 
        } 
 
 
 
Regards, 
Jai Ganesh S 


CONFIRMATION

This post will be permanently deleted. Are you sure you want to continue?

Sorry, An error occured while processing your request. Please try again later.

You are using an outdated version of Internet Explorer that may not display all features of this and other websites. Upgrade to Internet Explorer 8 or newer for a better experience.

;