Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WPF DataGrid performance issue affecting file list #5

Open
fadden opened this issue Nov 14, 2023 · 0 comments
Open

WPF DataGrid performance issue affecting file list #5

fadden opened this issue Nov 14, 2023 · 0 comments
Labels
bug Something isn't working

Comments

@fadden
Copy link
Owner

fadden commented Nov 14, 2023

First noted in 3f97bd1 .

Steps to reproduce:

  • Open a large archive, and select full-list display mode. I used "a2gemII.iso", but anything with a couple thousand entries ought to work.
  • Ensure the window is wide enough to show all columns.
  • Using the scroll bar, scroll down about halfway through the archive.
  • Close and reopen the archive.

When the archive is reopened, the program appears to stall, but eventually opens the file. When it does, the file list is positioned at the end of the archive, and the scroll bar is inactive. The debugger memory view shows a constant series of GCs. Clicking on any GUI element clears things up.

The main thread appears to be in a state of constant activity. Pausing the program to look at the stack trace shows it deep in WPF code (dozens of method calls down). The traces are a bit different every time, but often have something to do with dependency object property change events and DataGridRow objects.

The problem doesn't happen if the file list doesn't have a lot of elements in it. A large archive viewed with single-directory mode won't exhibit the problem (unless it has a lot of stuff in one directory). The width of the main window also matters. If the window is narrow enough to cut off part of the rightmost column ("Access"), the problem doesn't happen.

My best guess is that this has something to do with DataGrid virtualization, which is fraught with peril on a good day. Changing fileListDataGrid's VirtualizingStackPanel.VirtualizationMode value from "Recycling" to "Standard" changes the behavior somewhat. When the reproduction steps are followed, the load process will still appear to stall for a few seconds, showing the list scrolled all the way to the end. However, it will recover on its own, and move the file list position to the top. Again, partially obscuring the Access column fixes the issue.

(I tried setting the width of the Access column to "*" as a work-around, but for some reason the column width didn't change.)

The file list contents, which come out of an ObservableCollection in proper WPF fashion, are cleared when the file is closed. I even threw in an UpdateLayout() call to try to get it to return to its base state.

There's a second issue that is probably related to this one. Steps to reproduce:

  • Cause the problem as above. Click on a GUI element to un-freeze.
  • Shrink the right edge of the window so the Access column is partly obscured.
  • Close and reopen the archive.

When scrolling down, the leftmost column (status icon) will sometimes have a gray rectangle on the left side that pushes the line contents to the right. Not just for that column, but for the entire row, so the vertical column markers are out of whack.

image

The extra rect appears and disappears on a given line as the file list is scrolled, again suggesting the involvement of the GUI element recycling system. (Update: issue happens whether or not there is an icon present in the row.)

In any event, I believe this is a problem in WPF rather than the application code, but it may be possible to find a workaround that reduces the impact.

Update: today it isn't stalling, but it is spitting out about 70 of these when the archive is re-opened:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.DataGrid', AncestorLevel='1''. BindingExpression:Path=HeadersVisibility; DataItem=null; target element is 'DataGridRowHeader' (Name=''); target property is 'Visibility' (type 'Visibility')

Those messages and the extra rect go away if the recycling mode is changed to "standard". Curiously, switching between ProDOS volumes within a2gem.iso doesn't cause the messages to reappear; it's only when the archive is closed and reopened. The GUI elements are hidden, not discarded, when an archive is closed.

Update: none of the problems happen with the "release" build of 0.4.0. Maybe it's a debug-mode-only problem? That would be nice.

Update: it's stalling with the 1.0.0-alpha1 "release" builds (tried win-x86 and win-x64). Maybe I didn't have the window wide enough in the previous round of tests? I'm not seeing the secondary graphical glitches though.

fadden added a commit that referenced this issue Nov 24, 2023
This replaces the "dummy element" hack with the "binding proxy"
hack.  This is required to be able to hide DataGrid columns.

The goal was to improve the problems seen in issue #5, but this
doesn't seem to change that behavior.  (Technically, the behavior
has changed: the infinite GC issue isn't happening, and there's a
new series of binding complaints.  But that was true before I
started making changes.)

Yay WPF.
@fadden fadden added the bug Something isn't working label Jan 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant