Skip to content

Commit

Permalink
fix(measure_dirty_path): recycled ItemsControl not re-measuring
Browse files Browse the repository at this point in the history
  • Loading branch information
Xiaoy312 committed Jun 14, 2022
1 parent a5a2962 commit 6f87bb8
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
Expand Down Expand Up @@ -358,8 +358,47 @@ public async Task Check_ItemContainerStyle_ContentControl()
Assert.AreEqual(third.Style, containerStyle);
}

[TestMethod]
[RunsOnUIThread]
public async Task When_NestedItemsControl_RecycleTemplate()
{
var template = (DataTemplate)XamlReader.Load(@"
<DataTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'>
<ItemsControl ItemsSource='{Binding NestedSource}'
BorderBrush='Black' BorderThickness='1'>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Rectangle Fill='Red' Height='50' Width='50' />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
".Replace('\'', '"'));
var initialSource = new object[] { new { NestedSource = new object[1] }, };
var resetSource = new object[] { new { NestedSource = new object[0] }, };
var SUT = new ItemsControl()
{
ItemsSource = initialSource,
ItemTemplate = template,
};
WindowHelper.WindowContent = SUT;

var item = default(ContentPresenter);

// [initial stage]: load the nested ItemsControl with items, so it has an initial height
await WindowHelper.WaitForLoaded(SUT);
await WindowHelper.WaitFor(() => (item = SUT.ContainerFromItem(initialSource[0]) as ContentPresenter) != null, message: "initial state: failed to find the item");
Assert.AreEqual(50, item.ActualHeight, delta: 1.0, "initial state: expecting the item to have an starting height of 50");

// [reset stage]: ItemsSource is reset with empty NestedSource, and we expected the height to be RE-measured
SUT.ItemsSource = resetSource;
await WindowHelper.WaitForIdle();
await WindowHelper.WaitFor(() => (item = SUT.ContainerFromItem(resetSource[0]) as ContentPresenter) != null, message: "reset state: failed to find the item");
Assert.AreEqual(0, item.ActualHeight, "reset state: expecting the item's height to be remeasured to 0");
}

}

internal partial class ContentControlItemsControl : ItemsControl
{
protected override DependencyObject GetContainerForItemOverride() => new ContentControl();
Expand Down
5 changes: 5 additions & 0 deletions src/Uno.UI/UI/Xaml/UIElementCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ public void Clear()
}
}

if (_owner is FrameworkElement fe)
{
fe.InvalidateMeasure();
}

OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, items.ToList()));
}

Expand Down

0 comments on commit 6f87bb8

Please sign in to comment.