From d54c53426e7ccdd8a6a2d44ba92eb5973e1510f8 Mon Sep 17 00:00:00 2001 From: Shane Neuville Date: Wed, 13 Sep 2023 10:23:45 -0500 Subject: [PATCH] Revert changes to setting context and add tests --- .../Issues/Issue16787.cs | 48 +++++++++++++++++++ .../CollectionView/ItemContentControl.cs | 3 +- .../tests/UITests/Tests/Issues/Issue16787.cs | 20 ++++++++ 3 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 src/Controls/samples/Controls.Sample.UITests/Issues/Issue16787.cs create mode 100644 src/Controls/tests/UITests/Tests/Issues/Issue16787.cs diff --git a/src/Controls/samples/Controls.Sample.UITests/Issues/Issue16787.cs b/src/Controls/samples/Controls.Sample.UITests/Issues/Issue16787.cs new file mode 100644 index 000000000000..d1470218d46a --- /dev/null +++ b/src/Controls/samples/Controls.Sample.UITests/Issues/Issue16787.cs @@ -0,0 +1,48 @@ +using Microsoft.Maui.Controls; + +namespace Maui.Controls.Sample.Issues +{ + [Issue(IssueTracker.Github, 16787, "CollectionView runtime binding errors when loading the ItemSource asynchronously", PlatformAffected.UWP)] + public class Issue16787 : TestContentPage + { + protected override void OnBindingContextChanged() + { + base.OnBindingContextChanged(); + } + protected override void Init() + { + var cv = new CollectionView(); + cv.BindingContextChanged += Cv_BindingContextChanged; + this.BindingContext = this; + cv.ItemTemplate = new DataTemplate(() => + { + int bindingContextChanges = 0; + var label = new Label(); + label.BindingContextChanged += (_, _) => + { + bindingContextChanges++; + label.Text = bindingContextChanges.ToString(); + }; + label.AutomationId = "LabelBindingCount"; + return label; + }); + + cv.ItemsSource = new[] { "random" }; + + + var layout = new VerticalStackLayout() + { + new Label() + { + Text = "The value below this label should be a 1. That's how many times the BindingContext has changed on the Templated element" + } + }; + + Content = cv; + } + + private void Cv_BindingContextChanged(object sender, System.EventArgs e) + { + } + } +} diff --git a/src/Controls/src/Core/Platform/Windows/CollectionView/ItemContentControl.cs b/src/Controls/src/Core/Platform/Windows/CollectionView/ItemContentControl.cs index c41f7582bb70..22a4449f7c86 100644 --- a/src/Controls/src/Core/Platform/Windows/CollectionView/ItemContentControl.cs +++ b/src/Controls/src/Core/Platform/Windows/CollectionView/ItemContentControl.cs @@ -169,6 +169,7 @@ internal void Realize() // or if we need to switch DataTemplates (because this instance is being recycled) // then we'll need to create the content from the template _visualElement = formsTemplate.CreateContent(dataContext, container) as VisualElement; + _visualElement.BindingContext = dataContext; _renderer = _visualElement.ToHandler(mauiContext); // We need to set IsPlatformStateConsistent explicitly; otherwise, it won't be set until the renderer's Loaded @@ -186,11 +187,11 @@ internal void Realize() { // We are reusing this ItemContentControl and we can reuse the Element _visualElement = _renderer.VirtualView as VisualElement; + _visualElement.BindingContext = dataContext; } Content = _renderer.ToPlatform(); itemsView?.AddLogicalChild(_visualElement); - _visualElement.BindingContext = dataContext; } void SetNativeStateConsistent(VisualElement visualElement) diff --git a/src/Controls/tests/UITests/Tests/Issues/Issue16787.cs b/src/Controls/tests/UITests/Tests/Issues/Issue16787.cs new file mode 100644 index 000000000000..b9f804983697 --- /dev/null +++ b/src/Controls/tests/UITests/Tests/Issues/Issue16787.cs @@ -0,0 +1,20 @@ +using Microsoft.Maui.Appium; +using NUnit.Framework; + +namespace Microsoft.Maui.AppiumTests.Issues +{ + public class Issue16787 : _IssuesUITest + { + public Issue16787(TestDevice device) : base(device) + { + } + + public override string Issue => "CollectionView runtime binding errors when loading the ItemSource asynchronously"; + + [Test] + public void CollectionViewBindingContextOnlyChangesOnce() + { + Assert.AreEqual("1", App.WaitForElement("LabelBindingCount")[0].ReadText()); + } + } +}