Skip to content

Commit

Permalink
Merge pull request #7428 from unoplatform/dev/dr/cylicInvalidate
Browse files Browse the repository at this point in the history
fix: Make sure that an element can invalidate itself in Measure/Arrange
  • Loading branch information
mergify[bot] authored Nov 4, 2021
2 parents ebdea1f + 266ae34 commit a7c9943
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,7 @@ namespace Windows.UI.Xaml.Tests.MUXControls.ApiTests.RepeaterTests
public class LayoutTests : MUXApiTestBase
{
[TestMethod]
#if __IOS__ || __ANDROID__
[Ignore("UNO: Test does not pass yet with Uno https://github.com/unoplatform/uno/issues/4529")]
#endif
public void ValidateMappingAndAutoRecycling()
{
ItemsRepeater repeater = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,53 @@ public Task When_Measure_And_Invalidate() =>
Assert.AreEqual(new Size(10, 10), SUT.MeasureOverrides[1]);
});


[TestMethod]
[RunsOnUIThread]
#if __ANDROID__
[Ignore]
#endif
public async Task When_InvalidateDuringMeasure_Then_GetReMeasured()
{
var sut = new ObservableLayoutingControl();
var count = 0;
sut.OnMeasure += (snd, e) =>
{
if (count++ == 0)
{
snd.InvalidateMeasure();
}
};

TestServices.WindowHelper.WindowContent = sut;
await TestServices.WindowHelper.WaitForIdle();

Assert.AreEqual(2, count);
}

[TestMethod]
[RunsOnUIThread]
#if __ANDROID__
[Ignore]
#endif
public async Task When_InvalidateDuringArrange_Then_GetReArranged()
{
var sut = new ObservableLayoutingControl();
var count = 0;
sut.OnArrange += (snd, e) =>
{
if (count++ == 0)
{
snd.InvalidateArrange();
}
};

TestServices.WindowHelper.WindowContent = sut;
await TestServices.WindowHelper.WaitForIdle();

Assert.AreEqual(2, count);
}

[TestMethod]
public Task MeasureWithNan() =>
RunOnUIThread.ExecuteAsync(() =>
Expand Down Expand Up @@ -649,4 +696,24 @@ protected override Size MeasureOverride(Size availableSize)
return new Size(width, height);
}
}

public partial class ObservableLayoutingControl : FrameworkElement
{
public event TypedEventHandler<ObservableLayoutingControl, Size> OnMeasure;

public event TypedEventHandler<ObservableLayoutingControl, Size> OnArrange;

protected override Size MeasureOverride(Size availableSize)
{
OnMeasure?.Invoke(this, availableSize);
return new Size(100, 100);
}

/// <inheritdoc />
protected override Size ArrangeOverride(Size finalSize)
{
OnArrange?.Invoke(this, finalSize);
return new Size(100, 100);
}
}
}
8 changes: 6 additions & 2 deletions src/Uno.UI/UI/Xaml/UIElement.Layout.netstd.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,11 @@ private void DoMeasure(Size availableSize)
{
InvalidateArrange();

// We must reset the flag **BEFORE** doing the actual measure, so the elements are able to re-invalidate themselves
_isMeasureValid = true;

MeasureCore(availableSize);
LayoutInformation.SetAvailableSize(this, availableSize);
_isMeasureValid = true;
}

internal virtual void MeasureCore(Size availableSize)
Expand Down Expand Up @@ -205,8 +207,10 @@ private void DoArrange(Rect finalRect)
// For instance, the EffectiveViewPort computation reads that value to detect slot changes (cf. PropagateEffectiveViewportChange)
LayoutInformation.SetLayoutSlot(this, finalRect);

ArrangeCore(finalRect);
// We must reset the flag **BEFORE** doing the actual arrange, so the elements are able to re-invalidate themselves
_isArrangeValid = true;

ArrangeCore(finalRect);
}

partial void HideVisual();
Expand Down

0 comments on commit a7c9943

Please sign in to comment.