Search code examples
wpfscrollviewer

ScrollViewer.MeasureOverride settings ComputerScrollbarVisibility to Collapsed before setting it to the correct value


If VerticalScrollbarVisibility of a Scrollviewer is set to Auto, the MeasureOverride method of that ScrollViewer, first sets the ComputedVerticalScrollbarVisibility to Collapsed. Only then, it calculates the correct value and changes it again, if necessary. The same behavior for the horizontal scrollbar.

You can see this here: https://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/windows/Controls/ScrollViewer.cs,1202

We bind to the ComputedVerticalScrollbarVisibility property, triggering some margin changes. This triggers a MeasureOverride, resulting in a loop. We have other workarounds to fix this, but I'm wondering why it is coded that way.

Why is it first set to Collapsed, before setting the correct, calculated, value?


Solution

  • There is no definite answer to this. Only the author of the code knows why he is doing it this way.
    Your observation of the performance impact is the reason why Microsoft recommends to either disable the ScrollBar or explicitly enable it. The recommendation is, to always avoid having the scroll bar's visibility set to Auto.

    Optimizing Performance: Other Recommendations: Avoid Using ScrollBarVisibility=Auto:

    "The Auto value is intended for cases when space is limited and scrollbars should only be displayed when necessary. For example, it may be useful to use this ScrollBarVisibility value with a ListBox of 30 items as opposed to a TextBox with hundreds of lines of text."

    Which also answers your question: ScrollViewer must measure the "pure" content to check if scroll bars should be avoided. To do this, it takes a complete extra measure pass without scroll bars being added to the content.