Fix for #6444: Propagate binding context for children of shell sections (#6730)
authorChristopher Dresel <christopher.dresel@outlook.com>
Fri, 5 Jul 2019 18:29:42 +0000 (20:29 +0200)
committerShane Neuville <shneuvil@microsoft.com>
Fri, 5 Jul 2019 18:29:42 +0000 (12:29 -0600)
* Propagate binding context for children of shell sections

* Added a few more BindingContext Propagation tests

Xamarin.Forms.Core.UnitTests/ShellTests.cs
Xamarin.Forms.Core/Shell/ShellSection.cs

index 81c4a25..6ff189d 100644 (file)
@@ -33,6 +33,104 @@ namespace Xamarin.Forms.Core.UnitTests
                }
 
                [Test]
+               public void ShellChildrenBindingContext()
+               {
+                       var shell = new Shell();
+
+                       var shellItem = CreateShellItem();
+                       shell.Items.Add(shellItem);
+
+                       object viewModel = new object();
+                       shell.BindingContext = viewModel;
+
+                       Assert.AreSame(shell.BindingContext, viewModel);
+                       Assert.AreSame(shellItem.BindingContext, viewModel);
+                       Assert.AreSame(shellItem.Items[0].BindingContext, viewModel);
+                       Assert.AreSame(shellItem.Items[0].Items[0].BindingContext, viewModel);
+                       Assert.AreSame((shellItem.Items[0].Items[0].Content as BindableObject).BindingContext, viewModel);
+               }
+
+               [Test]
+               public void ShellPropagateBindingContextWhenAddingNewShellItem()
+               {
+                       var shell = new Shell();
+
+                       shell.Items.Add(CreateShellItem());
+
+                       object viewModel = new object();
+                       shell.BindingContext = viewModel;
+                       var shellItem = CreateShellItem();
+                       shell.Items.Add(shellItem);
+
+                       Assert.AreSame(shellItem.BindingContext, viewModel);
+                       Assert.AreSame(shellItem.Items[0].BindingContext, viewModel);
+                       Assert.AreSame(shellItem.Items[0].Items[0].BindingContext, viewModel);
+                       Assert.AreSame((shellItem.Items[0].Items[0].Content as BindableObject).BindingContext, viewModel);
+               }
+
+               [Test]
+               public void ShellPropagateBindingContextWhenAddingNewShellSection()
+               {
+                       var shell = new Shell();
+
+                       shell.Items.Add(CreateShellItem());
+
+                       object viewModel = new object();
+                       shell.BindingContext = viewModel;
+                       var shellSection = CreateShellSection();
+                       shell.Items[0].Items.Add(shellSection);
+
+                       Assert.AreSame(shellSection.BindingContext, viewModel);
+                       Assert.AreSame(shellSection.Items[0].BindingContext, viewModel);
+                       Assert.AreSame((shellSection.Items[0].Content as BindableObject).BindingContext, viewModel);
+               }
+
+               [Test]
+               public void ShellPropagateBindingContextWhenAddingNewShellContent()
+               {
+                       var shell = new Shell();
+
+                       shell.Items.Add(CreateShellItem());
+
+                       object viewModel = new object();
+                       shell.BindingContext = viewModel;
+                       var shellContent = CreateShellContent();
+                       shell.Items[0].Items[0].Items.Add(shellContent);
+
+                       Assert.AreSame(shellContent.BindingContext, viewModel);
+                       Assert.AreSame((shellContent.Content as BindableObject).BindingContext, viewModel);
+               }
+
+               [Test]
+               public void ShellPropagateBindingContextWhenChangingContent()
+               {
+                       var shell = new Shell();
+
+                       shell.Items.Add(CreateShellItem());
+
+                       object viewModel = new object();
+                       shell.BindingContext = viewModel;
+                       var contentPage = new ContentPage();
+
+                       shell.Items[0].Items[0].Items[0].Content = contentPage;
+                       Assert.AreSame(contentPage.BindingContext, viewModel);
+               }
+
+               [Test]
+               public async Task ShellPropagateBindingContextWhenPushingContent()
+               {
+                       var shell = new Shell();
+                       shell.Items.Add(CreateShellItem());
+
+                       object viewModel = new object();
+                       shell.BindingContext = viewModel;
+                       var contentPage = new ContentPage();
+                       await shell.Navigation.PushAsync(contentPage);
+
+                       Assert.AreSame(contentPage.BindingContext, viewModel);
+               }
+
+               [Test]
                public void NavigationProxyWireUpTest()
                {
                        var page = new ContentPage();
index fdc4a2d..d3c5027 100644 (file)
@@ -598,11 +598,20 @@ namespace Xamarin.Forms
                        }
                }
 
+               protected override void OnBindingContextChanged()
+               {
+                       base.OnBindingContextChanged();
+
+                       foreach (ShellContent shellContent in Items)
+                       {
+                               SetInheritedBindingContext(shellContent, BindingContext);
+                       }
+               }
+    
                internal override void SendDisappearing()
                {
                        base.SendDisappearing();
                        PresentedPageDisappearing();
-
                }
 
                internal override void SendAppearing()