Browse Source

Fix ScrollContentPresenter incorrectly handling BringIntoView when offset is coerced (#14913)

* Added failing test for nested ScrollContentPresenters w/o rounding

* Fix SCP.BringDescendantIntoView with coerced offset
release/11.1.0-beta2
Julien Lebosquain 2 years ago
committed by Max Katz
parent
commit
e238993aaa
  1. 6
      src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs
  2. 50
      tests/Avalonia.Controls.UnitTests/Presenters/ScrollContentPresenterTests.cs

6
src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs

@ -285,8 +285,12 @@ namespace Avalonia.Controls.Presenters
return false;
}
var oldOffset = Offset;
SetCurrentValue(OffsetProperty, offset);
return true;
// It's possible that the Offset coercion has changed the offset back to its previous value,
// this is common for floating point rounding errors.
return !Offset.NearlyEquals(oldOffset);
}
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)

50
tests/Avalonia.Controls.UnitTests/Presenters/ScrollContentPresenterTests.cs

@ -439,6 +439,56 @@ namespace Avalonia.Controls.UnitTests.Presenters
Assert.Equal(new Vector(0, 0), innerPresenter.Offset);
}
[Fact]
public void Nested_Presenters_Should_Scroll_Outer_When_Viewports_Are_Close()
{
ScrollContentPresenter innerPresenter;
Border border;
var outerPresenter = new ScrollContentPresenter
{
CanHorizontallyScroll = true,
CanVerticallyScroll = true,
Width = 100,
Height = 170.0568181818182,
UseLayoutRounding = false,
Content = innerPresenter = new ScrollContentPresenter
{
CanHorizontallyScroll = true,
CanVerticallyScroll = true,
Width = 100,
Height = 493.2613636363636,
UseLayoutRounding = false,
Content = new StackPanel
{
Children =
{
new Border
{
Height = 455.31818181818187,
UseLayoutRounding = false
},
(border = new Border {
Width = 100,
Height = 37.94318181818182,
UseLayoutRounding = false
})
}
}
}
};
innerPresenter.UpdateChild();
outerPresenter.UpdateChild();
outerPresenter.Measure(new Size(100, 170.0568181818182));
outerPresenter.Arrange(new Rect(0, 0, 100, 170.0568181818182));
border.BringIntoView();
Assert.Equal(new Vector(0, 323.20454545454544), outerPresenter.Offset);
Assert.Equal(new Vector(0, 0), innerPresenter.Offset);
}
private class TestControl : Control
{
public Size AvailableSize { get; private set; }

Loading…
Cancel
Save