Skip to content

Commit

Permalink
fix: Don't propagate DataContext via Border.Child
Browse files Browse the repository at this point in the history
Restore the Uno 2.x behaviour whereby Border.ChildProperty doesn't propagate inherited values (including DataContext) to the property value. The inheritance is handled by the visual tree in the normal case (since Child is always a view).

This restores the ability for the framework to call SetParent() to simulate a different inheritance hierarchy than the actual visual tree configuration, eg for AppBarButton using the native style.
  • Loading branch information
davidjohnoliver committed Oct 1, 2020
1 parent c70114f commit 0dc34bd
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<Page
x:Class="Uno.UI.RuntimeTests.Tests.Windows_UI_Xaml_Controls.FramePages.Page_With_AppBarButton_Visibility_Bound"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Uno.UI.RuntimeTests.Tests.Windows_UI_Xaml_Controls.FramePages"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

<Grid>
<CommandBar Content="Page with AppBarButton">
<CommandBar.PrimaryCommands>
<AppBarButton Visibility="{Binding ButtonVisibility, FallbackValue=Collapsed}">
<TextBlock x:Name="innerTextBlock"
x:FieldModifier="public"
Text="{Binding ButtonText}" />
</AppBarButton>
</CommandBar.PrimaryCommands>
</CommandBar>
</Grid>
</Page>
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238

namespace Uno.UI.RuntimeTests.Tests.Windows_UI_Xaml_Controls.FramePages
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class Page_With_AppBarButton_Visibility_Bound : Page
{
public Page_With_AppBarButton_Visibility_Bound()
{
this.InitializeComponent();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Uno.UI.RuntimeTests.Helpers;
using Uno.UI.RuntimeTests.Tests.Windows_UI_Xaml_Controls.FramePages;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using static Private.Infrastructure.TestServices;

namespace Uno.UI.RuntimeTests.Tests.Windows_UI_Xaml_Controls
{
[TestClass]
[RunsOnUIThread]
public class Given_AppBarButton
{
[TestMethod]
public async Task Check_DataContext_Propagation()
{
using (StyleHelper.UseNativeFrameNavigation())
{
var frame = new Frame();
WindowHelper.WindowContent = frame;
await WindowHelper.WaitForIdle();
frame.Navigate(typeof(Page_With_AppBarButton_Visibility_Bound));
await WindowHelper.WaitForIdle();
var page = frame.Content as Page_With_AppBarButton_Visibility_Bound;
Assert.IsNotNull(page);
page.DataContext = new MyContext();
await WindowHelper.WaitForIdle();
var tb = page.innerTextBlock;
Assert.IsNotNull(tb);
Assert.AreEqual("Archaeopteryx", tb.Text);
Assert.IsTrue(tb.ActualWidth > 0);
Assert.IsTrue(tb.ActualHeight > 0);
}
}

private class MyContext
{
public Visibility ButtonVisibility => Visibility.Visible;
public string ButtonText => "Archaeopteryx";
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Data;

namespace Uno.UI.RuntimeTests.Tests.Windows_UI_Xaml_Controls
{
[TestClass]
[RunsOnUIThread]
public class Given_Border
{
[TestMethod]
public void Check_DataContext_Propagation()
{
var tb = new TextBlock();
tb.SetBinding(TextBlock.TextProperty, new Binding { Path = new PropertyPath("TestText") });
var SUT = new Border
{
Child = tb
};

var root = new Grid
{
DataContext = new MyContext()
};

root.Children.Add(SUT);

Assert.AreEqual("Vampire squid", tb.Text);
}

private class MyContext
{
public string TestText => "Vampire squid";
}
}
}
4 changes: 4 additions & 0 deletions src/Uno.UI/UI/Xaml/Controls/Border/Border.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ public virtual UIElement Child
typeof(Border),
new FrameworkPropertyMetadata(
null,
// Since this is a view, inheritance is handled through the visual tree, rather than via the property. We explicitly
// disable the property-based propagation here to support the case where the Parent property is overridden to simulate
// a different inheritance hierarchy, as is done for some controls with native styles.
FrameworkPropertyMetadataOptions.ValueDoesNotInheritDataContext,
(s, e) => ((Border)s)?.OnChildChanged((UIElement)e.OldValue, (UIElement)e.NewValue)
)
);
Expand Down

0 comments on commit 0dc34bd

Please sign in to comment.