diff --git a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/ContentPresenter/ContentPresenter_Content_DataContext.xaml b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/ContentPresenter/ContentPresenter_Content_DataContext.xaml
new file mode 100644
index 0000000000000000000000000000000000000000..0b3a40a3a8ae057d70cfd596dc6aef6fc2b86e33
--- /dev/null
+++ b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/ContentPresenter/ContentPresenter_Content_DataContext.xaml
@@ -0,0 +1,143 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/ContentPresenter/ContentPresenter_Content_DataContext.xaml.cs b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/ContentPresenter/ContentPresenter_Content_DataContext.xaml.cs
new file mode 100644
index 0000000000000000000000000000000000000000..8814e561a27a0d796d3cf19bd7bbfbe86792b6e7
--- /dev/null
+++ b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/ContentPresenter/ContentPresenter_Content_DataContext.xaml.cs
@@ -0,0 +1,12 @@
+using Windows.UI.Xaml.Controls;
+
+namespace Uno.UI.RuntimeTests.Tests.Windows_UI_Xaml_Controls.ContentPresenterPages
+{
+ public sealed partial class ContentPresenter_Content_DataContext : UserControl
+ {
+ public ContentPresenter_Content_DataContext()
+ {
+ this.InitializeComponent();
+ }
+ }
+}
diff --git a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_ComboBox.cs b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_ComboBox.cs
index 121ccf70fd50d97280efbbab211b8a18eff70bb9..5cdc940d4b70990aae25d5c5f65a9bf0066e3ac7 100644
--- a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_ComboBox.cs
+++ b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_ComboBox.cs
@@ -12,6 +12,7 @@ using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using static Private.Infrastructure.TestServices;
using System.Collections.ObjectModel;
+using Windows.UI.Xaml.Data;
#if NETFX_CORE
using Uno.UI.Extensions;
@@ -611,6 +612,68 @@ namespace Uno.UI.RuntimeTests.Tests.Windows_UI_Xaml_Controls
}
#endif
+ [TestMethod]
+ public void When_SelectedItem_TwoWay_Binding()
+ {
+ var itemsControl = new ItemsControl()
+ {
+ ItemsPanel = new ItemsPanelTemplate(() => new StackPanel()),
+ ItemTemplate = new DataTemplate(() =>
+ {
+ var comboBox = new ComboBox();
+ comboBox.Name = "combo";
+
+ comboBox.SetBinding(ComboBox.ItemsSourceProperty, new Binding { Path = new("Numbers") });
+ comboBox.SetBinding(
+ ComboBox.SelectedItemProperty,
+ new Binding { Path = new("SelectedNumber"), Mode = BindingMode.TwoWay });
+
+ return comboBox;
+ })
+ };
+
+ var test = new[] {
+ new TwoWayBindingItem()
+ };
+
+ WindowHelper.WindowContent = itemsControl;
+
+ itemsControl.ItemsSource = test;
+
+ var comboBox = itemsControl.FindName("combo") as ComboBox;
+
+ Assert.AreEqual(3, test[0].SelectedNumber);
+ Assert.AreEqual(3, comboBox.SelectedItem);
+ }
+
+ public class TwoWayBindingItem : System.ComponentModel.INotifyPropertyChanged
+ {
+ private int _selectedNumber;
+
+ public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
+
+ public TwoWayBindingItem()
+ {
+ Numbers = new List { 1, 2, 3, 4 };
+ SelectedNumber = 3;
+ }
+
+ public List Numbers { get; }
+
+ public int SelectedNumber
+ {
+ get
+ {
+ return _selectedNumber;
+ }
+ set
+ {
+ _selectedNumber = value;
+ PropertyChanged?.Invoke(this, new(nameof(Item)));
+ }
+ }
+ }
+
public class ItemModel
{
public string Text { get; set; }
diff --git a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_ContentPresenter.cs b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_ContentPresenter.cs
index fa0b6aec650e56e8d196ce2d495b7f268cdccf14..693f42355ad68417e3cce5381e0608a3425b6fe8 100644
--- a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_ContentPresenter.cs
+++ b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_ContentPresenter.cs
@@ -5,6 +5,7 @@ using System.Linq;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Private.Infrastructure;
+using Uno.UI.RuntimeTests.Tests.Windows_UI_Xaml_Controls.ContentPresenterPages;
using Windows.Foundation;
using Windows.UI;
using Windows.UI.Xaml;
@@ -35,6 +36,113 @@ public class Given_ContentPresenter
Assert.AreEqual(HorizontalAlignment.Stretch, border.HorizontalAlignment);
}
+ [TestMethod]
+ public void When_Binding_And_DataContext_Same_As_Content()
+ {
+ var SUT = new ContentPresenter();
+ var dataContextChangedCount = 0;
+
+ SUT.DataContextChanged += (s, e) => dataContextChangedCount++;
+
+ SUT.DataContext = new object();
+ SUT.Content = SUT.DataContext;
+
+ TestServices.WindowHelper.WindowContent = SUT;
+
+ // This test ensures that the ContentPresenter does not reset
+ // the DataContext to null and then back to the content and have
+ // two-way bindings propagating the null value back to the source.
+ Assert.AreEqual(1, dataContextChangedCount);
+ }
+
+ [TestMethod]
+ public void When_Content_Presenter_Empty()
+ {
+ var sut = new ContentPresenter_Content_DataContext();
+
+ TestServices.WindowHelper.WindowContent = sut;
+
+ Assert.AreEqual("", GetTextBlockText(sut, "emptyTest"));
+
+ sut.emptyTestRoot.DataContext = "43";
+
+ Assert.AreEqual("43", GetTextBlockText(sut, "emptyTest"));
+ }
+
+ [TestMethod]
+ public void When_Content_Presenter_Priority()
+ {
+ var sut = new ContentPresenter_Content_DataContext();
+
+ TestServices.WindowHelper.WindowContent = sut;
+
+ Assert.AreEqual("43", GetTextBlockText(sut, "priorityTest"));
+
+ sut.priorityTestRoot.DataContext = "44";
+ Assert.AreEqual("44", GetTextBlockText(sut, "priorityTest"));
+
+ sut.priorityTestRoot.Content = "45";
+ Assert.AreEqual("45", GetTextBlockText(sut, "priorityTest"));
+
+ sut.priorityTestRoot.DataContext = "46";
+ Assert.AreEqual("46", GetTextBlockText(sut, "priorityTest"));
+ }
+
+ [TestMethod]
+ public void When_Content_Presenter_SameValue()
+ {
+ var sut = new ContentPresenter_Content_DataContext();
+
+ TestServices.WindowHelper.WindowContent = sut;
+
+ Assert.AreEqual("42", GetTextBlockText(sut, "sameValueTest"));
+ }
+
+ [TestMethod]
+ public void When_Content_Presenter_Inheritance()
+ {
+ var sut = new ContentPresenter_Content_DataContext();
+
+ TestServices.WindowHelper.WindowContent = sut;
+
+ Assert.AreEqual("DataContext", GetTextBlockText(sut, "inheritanceTest"));
+
+ sut.inheritanceTestRoot.DataContext = "46";
+ Assert.AreEqual("46", GetTextBlockText(sut, "inheritanceTest"));
+
+ sut.inheritanceTestRoot.DataContext = "47";
+ Assert.AreEqual("47", GetTextBlockText(sut, "inheritanceTest"));
+
+ sut.inheritanceTestInner.DataContext = "48";
+ Assert.AreEqual("48", GetTextBlockText(sut, "inheritanceTest"));
+
+ sut.inheritanceTestRoot.DataContext = "49";
+ Assert.AreEqual("48", GetTextBlockText(sut, "inheritanceTest"));
+ }
+
+ [TestMethod]
+ public void When_Content_Presenter_SameValue_Changing()
+ {
+ var sut = new ContentPresenter_Content_DataContext();
+
+ TestServices.WindowHelper.WindowContent = sut;
+
+ Assert.AreEqual("DataContext", GetTextBlockText(sut, "sameValueChangingTest"));
+ }
+
+ [TestMethod]
+ public void When_Content_Presenter_Null_Content_Changed()
+ {
+ var sut = new ContentPresenter_Content_DataContext();
+
+ TestServices.WindowHelper.WindowContent = sut;
+
+ Assert.AreEqual("42", GetTextBlockText(sut, "nullContentChanged"));
+ }
+
+ static string GetTextBlockText(FrameworkElement sut, string v)
+ => (sut.FindName(v) as TextBlock)?.Text ?? "";
+
public static IEnumerable