Skip to content

Commit e158eec

Browse files
Fix repeater holding onto elements (#1723)
* If a consumer changes the ItemsSource with a non recycling layout then the items from the old source would be perpetually held by repeater, a potentially substantial leak. * Add a test
1 parent d29aac1 commit e158eec

File tree

2 files changed

+32
-0
lines changed

2 files changed

+32
-0
lines changed

dev/Repeater/APITests/RepeaterTests.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
using System.Collections.ObjectModel;
2929
using System.Threading;
3030
using System.Collections.Generic;
31+
using Windows.UI.Xaml.Tests.MUXControls.ApiTests.RepeaterTests.Common.Mocks;
3132

3233
namespace Windows.UI.Xaml.Tests.MUXControls.ApiTests.RepeaterTests
3334
{
@@ -145,6 +146,35 @@ public void ValidateGetSetItemsSource()
145146
});
146147
}
147148

149+
[TestMethod]
150+
public void VerifyClearingItemsSourceClearsElements()
151+
{
152+
var data = new ObservableCollection<string>(Enumerable.Range(0, 4).Select(i => "Item #" + i));
153+
var mapping = (List<ContentControl>)null;
154+
155+
RunOnUIThread.Execute(() =>
156+
{
157+
mapping = Enumerable.Range(0, data.Count).Select(i => new ContentControl { Width = 40, Height = 40 }).ToList();
158+
159+
var dataSource = MockItemsSource.CreateDataSource(data, supportsUniqueIds: false);
160+
var elementFactory = MockElementFactory.CreateElementFactory(mapping);
161+
ItemsRepeater repeater = new ItemsRepeater();
162+
repeater.ItemsSource = dataSource;
163+
repeater.ItemTemplate = elementFactory;
164+
// This was an issue only for NonVirtualizing layouts
165+
repeater.Layout = new MyCustomNonVirtualizingStackLayout();
166+
Content = repeater;
167+
Content.UpdateLayout();
168+
169+
repeater.ItemsSource = null;
170+
});
171+
172+
foreach(var item in mapping)
173+
{
174+
Verify.IsNull(item.Parent);
175+
}
176+
}
177+
148178
[TestMethod]
149179
public void ValidateGetSetBackground()
150180
{

dev/Repeater/ItemsRepeater.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,8 @@ void ItemsRepeater::OnDataSourcePropertyChanged(const winrt::ItemsSourceView& ol
546546
ClearElementImpl(element);
547547
}
548548
}
549+
550+
Children().Clear();
549551
}
550552

551553
InvalidateMeasure();

0 commit comments

Comments
 (0)