2
0
mirror of https://github.com/9ParsonsB/Pulsar.git synced 2025-07-01 08:23:42 -04:00

[Core + Framework] Performance improvements for re-drawing the grid (#141)

This proposes a *new method* on IObservatoryCore:  `SetGridItems(worker, items)` which does 2 things:
* Clears the grid
* Adds the given items.

Effectively replaces the entire content of the grid -- which is something a handful of plugins now do.

Why add this when you could just call Core's Clear + AddGridItems methods?? So it can all be done within the same rendering suppression "scope" to reduce flickering and increase rendering speed.  Speaking of rendering suppression, I have implemented such rendering suppression "scope" which uses Listview's built-in Begin/EndUpdate() in combination with temporary removal of the sort comparer (as is done for read-alls).  This was also applied to the existing AddGridItems(worker, items) method as well, addressing a TODO.
This commit is contained in:
F K
2024-01-30 20:49:53 -05:00
committed by GitHub
parent f4759072d2
commit 231710ca68
5 changed files with 89 additions and 6 deletions

View File

@ -2,6 +2,7 @@
using Observatory.Framework.Files;
using Observatory.Framework.Interfaces;
using Observatory.NativeNotification;
using Observatory.UI;
using Observatory.Utils;
using System;
using System.Collections.ObjectModel;
@ -114,11 +115,27 @@ namespace Observatory.PluginManagement
public void AddGridItems(IObservatoryWorker worker, IEnumerable<object> items)
{
//TODO: Use better bulk handling here.
BeginBulkUpdate(worker);
foreach (var item in items)
{
worker.PluginUI.DataGrid.Add(item);
}
EndBulkUpdate(worker);
}
public void SetGridItems(IObservatoryWorker worker, IEnumerable<object> items)
{
BeginBulkUpdate(worker);
worker.PluginUI.DataGrid.Clear();
foreach (var item in items)
{
worker.PluginUI.DataGrid.Add(item);
}
EndBulkUpdate(worker);
}
public void ClearGrid(IObservatoryWorker worker, object templateItem)
@ -186,5 +203,40 @@ namespace Observatory.PluginManagement
{
NativePopup.CloseAll();
}
private void BeginBulkUpdate(IObservatoryWorker worker)
{
PluginListView? listView = FindPluginListView(worker);
if (listView == null) return;
ExecuteOnUIThread(() => { listView.SuspendDrawing(); });
}
private void EndBulkUpdate(IObservatoryWorker worker)
{
PluginListView? listView = FindPluginListView(worker);
if (listView == null) return;
ExecuteOnUIThread(() => { listView.ResumeDrawing(); });
}
private PluginListView? FindPluginListView(IObservatoryWorker worker)
{
if (worker.PluginUI.PluginUIType != PluginUI.UIType.Basic
|| !(worker.PluginUI.UI is Panel)) return null;
PluginListView? listView = null;
Panel panel = worker.PluginUI.UI as Panel;
foreach (var control in panel.Controls)
{
if (control?.GetType() == typeof(PluginListView))
{
listView = (PluginListView)control;
return listView;
}
}
return null;
}
}
}

View File

@ -61,6 +61,7 @@ namespace Observatory.UI
{
Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Bottom | AnchorStyles.Top
};
plugin.PluginUI.UI = panel;
IObservatoryComparer columnSorter;
if (plugin.ColumnSorter != null)

View File

@ -1,20 +1,17 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Observatory.UI
{
internal class PluginListView : ListView
{
[DllImport("user32.dll")]
private static extern int SendMessage(IntPtr hWnd, int wMsg, bool wParam, int lParam);
private const int WM_SETREDRAW = 11;
public PluginListView()
{
OwnerDraw = true;
@ -28,6 +25,25 @@ namespace Observatory.UI
base.GridLines = false;//We should prevent the default drawing of gridlines.
}
// Stash for performance when doing large UI updates.
private IComparer? comparer = null;
public void SuspendDrawing()
{
BeginUpdate();
comparer = ListViewItemSorter;
}
public void ResumeDrawing()
{
if (comparer != null)
{
ListViewItemSorter = comparer;
comparer = null;
}
EndUpdate();
}
private static void DrawBorder(Graphics graphics, Pen pen, Rectangle bounds, bool header = false)
{