public void ValidateMappingAndAutoRecycling() { ItemsRepeater repeater = null; ScrollViewer scrollViewer = null; RunOnUIThread.Execute(() => { var layout = new MockVirtualizingLayout() { MeasureLayoutFunc = (availableSize, context) => { var element0 = context.GetOrCreateElementAt(index: 0); // lookup - repeater will give back the same element and note that this element will not // be pinned - i.e it will be auto recycled after a measure pass where GetElementAt(0) is not called. var element0lookup = context.GetOrCreateElementAt(index: 0, options: ElementRealizationOptions.None); var element1 = context.GetOrCreateElementAt(index: 1, options: ElementRealizationOptions.ForceCreate | ElementRealizationOptions.SuppressAutoRecycle); // forcing a new element for index 1 that will be pinned (not auto recycled). This will be // a completely new element. Repeater does not do the mapping/lookup when forceCreate is true. var element1Clone = context.GetOrCreateElementAt(index: 1, options: ElementRealizationOptions.ForceCreate | ElementRealizationOptions.SuppressAutoRecycle); Verify.AreSame(element0, element0lookup); Verify.AreNotSame(element1, element1Clone); element0.Measure(availableSize); element1.Measure(availableSize); element1Clone.Measure(availableSize); return(new Size(100, 100)); }, }; Content = CreateAndInitializeRepeater( itemsSource: Enumerable.Range(0, 5), layout: layout, elementFactory: GetDataTemplate("<Button>Hello</Button>"), repeater: ref repeater, scrollViewer: ref scrollViewer); Content.UpdateLayout(); Verify.IsNotNull(repeater.TryGetElement(0)); Verify.IsNotNull(repeater.TryGetElement(1)); layout.MeasureLayoutFunc = null; repeater.InvalidateMeasure(); Content.UpdateLayout(); Verify.IsNull(repeater.TryGetElement(0)); // not pinned, should be auto recycled. Verify.IsNotNull(repeater.TryGetElement(1)); // pinned, should stay alive }); }