Skip to content

Commit

Permalink
fix(NameScope): Ensure NameScope is not overriden for XAML backed con…
Browse files Browse the repository at this point in the history
…trols
  • Loading branch information
jeromelaban committed Feb 19, 2022
1 parent 8e4aa1a commit b2c8a47
Show file tree
Hide file tree
Showing 13 changed files with 408 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -889,8 +889,12 @@ private void BuildChildSubclasses(IIndentedStringBuilder writer, bool isTopLevel

using (writer.BlockInvariant("if (__rootInstance is DependencyObject d)", kvp.Value.ReturnType))
{
writer.AppendLineInvariant("global::Windows.UI.Xaml.NameScope.SetNameScope(d, nameScope);");
writer.AppendLineInvariant("nameScope.Owner = d;");
using (writer.BlockInvariant("if (global::Windows.UI.Xaml.NameScope.GetNameScope(d) == null)", kvp.Value.ReturnType))
{
writer.AppendLineInvariant("global::Windows.UI.Xaml.NameScope.SetNameScope(d, nameScope);");
writer.AppendLineInvariant("nameScope.Owner = d;");
}

writer.AppendLineInvariant("global::Uno.UI.FrameworkElementHelper.AddObjectReference(d, this);");
}

Expand Down
17 changes: 17 additions & 0 deletions src/Uno.UI.Tests/Windows_UI_Xaml/Controls/When_NameScope.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<UserControl
x:Class="Uno.UI.Tests.Windows_UI_Xaml.Controls.When_NameScope"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Uno.UI.Tests.Windows_UI_Xaml.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Name="OuterElementTopLevel"
x:FieldModifier="public"
mc:Ignorable="d">
<Grid>
<local:When_NameScope_Inner x:Name="OuterElementName"
x:FieldModifier="public" />
<Grid x:Name="OuterBorder"
x:FieldModifier="public" />
</Grid>
</UserControl>
28 changes: 28 additions & 0 deletions src/Uno.UI.Tests/Windows_UI_Xaml/Controls/When_NameScope.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
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.Markup;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236

namespace Uno.UI.Tests.Windows_UI_Xaml.Controls
{
public sealed partial class When_NameScope : UserControl
{
public When_NameScope()
{
this.InitializeComponent();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<UserControl
x:Class="Uno.UI.Tests.Windows_UI_Xaml.Controls.When_NameScope_DataTemplate"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Uno.UI.Tests.Windows_UI_Xaml.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Name="OuterElementTopLevel"
x:FieldModifier="public"
mc:Ignorable="d">
<Grid>
<ContentControl x:Name="content01" Content="42">
<ContentControl.ContentTemplate>
<DataTemplate>
<local:When_NameScope_Inner x:Name="OuterElementName"
x:FieldModifier="public" />
</DataTemplate>
</ContentControl.ContentTemplate>
</ContentControl>
<Grid x:Name="OuterBorder"
x:FieldModifier="public" />
</Grid>
</UserControl>
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
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.Markup;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236

namespace Uno.UI.Tests.Windows_UI_Xaml.Controls
{
public sealed partial class When_NameScope_DataTemplate : UserControl
{
public When_NameScope_DataTemplate()
{
this.InitializeComponent();
Loaded += delegate {
OuterElementName = (content01.ContentTemplateRoot as FrameworkElement).FindName("OuterElementName") as When_NameScope_Inner;
};
}

public When_NameScope_Inner OuterElementName { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<UserControl
x:Class="Uno.UI.Tests.Windows_UI_Xaml.Controls.When_NameScope_Inner"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Uno.UI.Tests.Windows_UI_Xaml.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Name="InnerElementTopLevel"
x:FieldModifier="public"
mc:Ignorable="d">
<Grid>
<Border x:Name="InnerBorder"
x:FieldModifier="public" />
</Grid>

</UserControl>
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
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.Markup;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

namespace Uno.UI.Tests.Windows_UI_Xaml.Controls
{
public sealed partial class When_NameScope_Inner : UserControl
{
public When_NameScope_Inner()
{
this.InitializeComponent();
}
}
}
116 changes: 116 additions & 0 deletions src/Uno.UI.Tests/Windows_UI_Xaml/Given_Namescope.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Uno.UI.Tests.Windows_UI_Xaml.Controls;
using Windows.UI.Xaml;

namespace Uno.UI.Tests.Windows_UI_Xaml
{
[TestClass]
public class Given_NameScope
{
[TestInitialize]
public void Init()
{
UnitTestsApp.App.EnsureApplication();
}

[TestMethod]
public void When_NameScope()
{
var SUT = new When_NameScope();
SUT.ForceLoaded();

var OuterElementName = NameScope.FindInNamescopes(
SUT,
nameof(SUT.OuterElementName)) as FrameworkElement;
var OuterBorder = NameScope.FindInNamescopes(
SUT,
nameof(SUT.OuterBorder)) as FrameworkElement;

Assert.IsNotNull(OuterElementName);
Assert.IsNotNull(OuterBorder);

var OuterElementTopLevelFromOuterBorder = NameScope.FindInNamescopes(
OuterBorder,
nameof(SUT.OuterElementTopLevel)) as FrameworkElement;
Assert.IsNotNull(OuterElementTopLevelFromOuterBorder);

// search through visual tree walking
var OuterElementTopLevelFromOuterElementName = NameScope.FindInNamescopes(
OuterElementName,
nameof(SUT.OuterElementTopLevel)) as FrameworkElement;
var OuterBorderFromOuterElementName = NameScope.FindInNamescopes(
OuterElementName,
nameof(SUT.OuterBorder)) as FrameworkElement;

Assert.IsNotNull(OuterElementTopLevelFromOuterElementName);
Assert.IsNotNull(OuterBorderFromOuterElementName);

// search via namescope
var InnerBorderFromOuterElementName = NameScope.FindInNamescopes(
SUT.OuterElementName as FrameworkElement,
nameof(When_NameScope_Inner.InnerBorder)) as FrameworkElement;
Assert.IsNotNull(InnerBorderFromOuterElementName);

var InnerBorderFromOuterElementNameContent = NameScope.FindInNamescopes(
SUT.OuterElementName.Content as FrameworkElement,
nameof(When_NameScope_Inner.InnerBorder)) as FrameworkElement;
Assert.IsNotNull(InnerBorderFromOuterElementNameContent);

// Search through namescope from the inner element to the inner top level name
var InnerElementTopLevelFromInnerBorder = NameScope.FindInNamescopes(
InnerBorderFromOuterElementNameContent,
nameof(When_NameScope_Inner.InnerElementTopLevel)) as FrameworkElement;
Assert.IsNotNull(InnerBorderFromOuterElementNameContent);
Assert.AreEqual(InnerElementTopLevelFromInnerBorder.Name, "OuterElementName");
}

[TestMethod]
public void When_NameScope_DataTemplate()
{
var SUT = new When_NameScope_DataTemplate();
SUT.ForceLoaded();

var OuterBorder = NameScope.FindInNamescopes(
SUT,
nameof(SUT.OuterBorder)) as FrameworkElement;

Assert.IsNotNull(SUT.OuterElementName);
Assert.IsNotNull(OuterBorder);

var OuterElementTopLevelFromOuterBorder = NameScope.FindInNamescopes(
OuterBorder,
nameof(SUT.OuterElementTopLevel)) as FrameworkElement;
Assert.IsNotNull(OuterElementTopLevelFromOuterBorder);

// search through visual tree walking
var OuterElementTopLevelFromOuterElementName = NameScope.FindInNamescopes(
SUT.OuterElementName,
nameof(SUT.OuterElementTopLevel)) as FrameworkElement;
var OuterBorderFromOuterElementName = NameScope.FindInNamescopes(
SUT.OuterElementName,
nameof(SUT.OuterBorder)) as FrameworkElement;

Assert.IsNotNull(OuterElementTopLevelFromOuterElementName);
Assert.IsNotNull(OuterBorderFromOuterElementName);

// search via namescope
var InnerBorderFromOuterElementName = NameScope.FindInNamescopes(
SUT.OuterElementName as FrameworkElement,
nameof(When_NameScope_Inner.InnerBorder)) as FrameworkElement;
Assert.IsNotNull(InnerBorderFromOuterElementName);

var InnerBorderFromOuterElementNameContent = NameScope.FindInNamescopes(
SUT.OuterElementName.Content as FrameworkElement,
nameof(When_NameScope_Inner.InnerBorder)) as FrameworkElement;
Assert.IsNotNull(InnerBorderFromOuterElementNameContent);

// Search through namescope from the inner element to the inner top level name
var InnerElementTopLevelFromInnerBorder = NameScope.FindInNamescopes(
InnerBorderFromOuterElementNameContent,
nameof(When_NameScope_Inner.InnerElementTopLevel)) as FrameworkElement;
Assert.IsNotNull(InnerBorderFromOuterElementNameContent);

Assert.AreEqual(InnerElementTopLevelFromInnerBorder.Name, "OuterElementName");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<Page x:Class="Uno.UI.Tests.Windows_UI_Xaml_Data.BindingTests.Controls.Binding_ElementName_In_Template_ItemsControl_Nested"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:Uno.UI.Tests.Windows_UI_Xaml_Data.xBindTests.Controls"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Name="ThisPage"
Tag="42"
mc:Ignorable="d">

<ItemsControl x:Name="SecondaryActionsList" x:FieldModifier="public">
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<ItemsPresenter/>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<Button x:Name="button"
Tag="{Binding Tag, ElementName=ThisPage}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Page>
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
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.Tests.Windows_UI_Xaml_Data.BindingTests.Controls
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class Binding_ElementName_In_Template_ItemsControl_Nested : Page
{
public Binding_ElementName_In_Template_ItemsControl_Nested()
{
this.InitializeComponent();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<Page x:Class="Uno.UI.Tests.Windows_UI_Xaml_Data.BindingTests.Controls.Binding_ElementName_In_Template_ItemsControl_Nested_Outer"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:Uno.UI.Tests.Windows_UI_Xaml_Data.xBindTests.Controls"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Name="OuterPage"
Tag="42"
mc:Ignorable="d">

<ItemsControl x:Name="PrimaryActionsList" x:FieldModifier="public">
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<ItemsPresenter/>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:Binding_ElementName_In_Template_ItemsControl_Nested Tag="{Binding Tag, ElementName=OuterPage}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Page>
Loading

0 comments on commit b2c8a47

Please sign in to comment.