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?
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.