xyzzer / WinRTXamlToolkit

WinRT XAML Toolkit
Other
282 stars 67 forks source link

WrapPanel: last item not wrapped correctly #30

Closed sr258 closed 8 years ago

sr258 commented 8 years ago

I've noticed that there seems to be a bug in WrapPanel that only occurs under quite limited circumstances that are a bit hard to reproduce:

Sometimes the last item of the WrapPanel is put into a new line even though it actually fits into the line before. The WrapPanel is correctly measured, but the last item is put into the wrong line when arranged. It is clearly visible that MeasureOverride works correctly and ArrangeOverride doesn't as the item is drawn partly "outside" the WrapPanel's constraints.

This does not happen on my developer machine but only occurs on my Surface 3 test device. I assume that it has something to do with dpi scaling.

Does anyone know about this issue or know how dpi scaling can affect working with absolute sizes?

sr258 commented 8 years ago

I've finally had some time to look into the issue and I've solved it. So, in case anyone else has this problem:

The problem occured in resolutions with other scaling factors than 100% (e.g. 140% or 180%). The reason for the layout error is that the call of NumericExtensions.IsGreaterThan(lineSize.Direct + elementSize.Direct, maximumSize.Direct) in WrapPanel.ArrangeOverride() returns true for the last item of the list in some cases if the left and right are nearly identical (the last item should fit exactly into the panel as the panel was sized for it to fit!). It seems as if NumericExtensions.AreClose() isn't tolerant enough for scaling factors other than 100%. I've fixed this by adding some tolerance to the maximumSize variable:

OrientedSize maximumSize = new OrientedSize(o, finalSize.Width + TOLERANCE, finalSize.Height + TOLERANCE); // TOLERANCE = 0.001d;

This works but doesn't seem terribly elegant, that's why I haven't done a pull request.