picoe / Eto

Cross platform GUI framework for desktop and mobile applications in .NET
Other
3.57k stars 325 forks source link

Wpf: GridView.ReloadData(...) is very slow #2245

Open Serg-Norseman opened 2 years ago

Serg-Norseman commented 2 years ago

/src/Eto.Wpf/Forms/Controls/GridHandler.cs

        public void ReloadData(IEnumerable<int> rows)
        {
            Control.Items.Refresh();
        }

/src/Eto.WinForms/Forms/Controls/GridHandler.cs

        public void ReloadData(IEnumerable<int> rows)
        {
            Control.Refresh();
        }

On Mac and Gtk, the methods are written differently, it probably works good there.

devmaestro1 commented 2 years ago

Hello, have you tried to only update the row that was updated?

Serg-Norseman commented 2 years ago

I'm using a GridView on a datasource (ObservableCollection) with content ranging from a few hundred to a few million rows. Some rows are highlighted/formatted depending on the data content (CellFormatting handler). Row formatting works correctly, but: when the selected row changes (SelectedRow property) - CellFormatting is not called by default. Therefore, the row selected by the user has the color of the background and text - formatting (not "Selection" and "SelectionText", #2242). This problem is solved by calling ReloadData(SelectedRow) from SelectionChanged and immediately checking in CellFormatting: if (e.Row == SelectedRow) { e.BackgroundColor = SystemColors.Selection; e.ForegroundColor = SystemColors.SelectionText; return; } , but here the described problem arises: in Gtk and Mac implementations of GridHandler ReloadData(SelectedRow) leads to updating only the passed row. And in Wpf implementation of GridHandler - to update the entire items list. Therefore, clicking on any row leads to "freezing" noticeable to the user.

P.S. I will try to pass the change event of a particular item to the ObservableCollection. Perhaps this will give an indirect call to ReloadData only for the desired item and, accordingly, reformatting only the selected row. But it seems to me that this is not the right way. Even if it works, it's a botch over bug, not a bug fix.

Serg-Norseman commented 2 years ago

Hello, have you tried to only update the row that was updated?

I've searched and so far I don't see the possibility within the INotifyCollectionChanged or INotifyPropertyChanged interfaces to send the desired notification