Skip to content

Commit

Permalink
fix: Make sure that an element can invalidate itself (and its parents…
Browse files Browse the repository at this point in the history
…) while in being measured / arranged
  • Loading branch information
dr1rrb committed Nov 3, 2021
1 parent 3127b7f commit 6f30b05
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,47 @@ public Task When_Measure_And_Invalidate() =>
Assert.AreEqual(new Size(10, 10), SUT.MeasureOverrides[1]);
});


[TestMethod]
[RunsOnUIThread]
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]
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 +690,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 6f30b05

Please sign in to comment.