From ce00ff4c9440b0ae7e5a0b8a3fe706315d4038af Mon Sep 17 00:00:00 2001 From: Carl de Billy Date: Wed, 19 Jun 2019 11:36:15 -0400 Subject: [PATCH] Added support for "BasedOn" on styles in App.Xaml Fix #854 --- src/SamplesApp/SamplesApp.Shared/App.xaml | 38 ++++++++++++++++++ src/SamplesApp/SamplesApp.Shared/App.xaml.cs | 5 +-- .../UITests.Shared/UITests.Shared.projitems | 8 ++++ .../Resources/XamlGlobalResources.xaml | 27 +++++++++++++ .../Resources/XamlGlobalResources.xaml.cs | 16 ++++++++ src/Uno.UI/FeatureConfiguration.cs | 11 +++++ .../Xaml/Markup/Reader/XamlObjectBuilder.cs | 7 +++- .../Markup/Reader/XamlObjectDefinition.cs | 18 ++++----- src/Uno.UI/UI/Xaml/ResourceDictionary.cs | 40 ++++++------------- 9 files changed, 129 insertions(+), 41 deletions(-) create mode 100644 src/SamplesApp/UITests.Shared/Windows_UI_Xaml/Resources/XamlGlobalResources.xaml create mode 100644 src/SamplesApp/UITests.Shared/Windows_UI_Xaml/Resources/XamlGlobalResources.xaml.cs diff --git a/src/SamplesApp/SamplesApp.Shared/App.xaml b/src/SamplesApp/SamplesApp.Shared/App.xaml index df8d85c0e7e3..174e677a4bba 100644 --- a/src/SamplesApp/SamplesApp.Shared/App.xaml +++ b/src/SamplesApp/SamplesApp.Shared/App.xaml @@ -4,4 +4,42 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" RequestedTheme="Light"> + + + + + + + + + + + + + + + + + + diff --git a/src/SamplesApp/SamplesApp.Shared/App.xaml.cs b/src/SamplesApp/SamplesApp.Shared/App.xaml.cs index 63789a78672c..1646c73e206e 100644 --- a/src/SamplesApp/SamplesApp.Shared/App.xaml.cs +++ b/src/SamplesApp/SamplesApp.Shared/App.xaml.cs @@ -51,9 +51,8 @@ public App() protected override void OnLaunched(LaunchActivatedEventArgs e) { var sw = Stopwatch.StartNew(); - var n = Windows.UI.Xaml.Window.Current.Dispatcher.RunAsync( - CoreDispatcherPriority.Idle, - () => Console.WriteLine("Done loading " + sw.Elapsed)); + var n = Windows.UI.Xaml.Window.Current.Dispatcher.RunIdleAsync( + _ => Console.WriteLine("Done loading " + sw.Elapsed)); #if DEBUG if (System.Diagnostics.Debugger.IsAttached) diff --git a/src/SamplesApp/UITests.Shared/UITests.Shared.projitems b/src/SamplesApp/UITests.Shared/UITests.Shared.projitems index 95162145f7c1..b6b447e1640c 100644 --- a/src/SamplesApp/UITests.Shared/UITests.Shared.projitems +++ b/src/SamplesApp/UITests.Shared/UITests.Shared.projitems @@ -109,6 +109,10 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + Designer MSBuild:Compile @@ -2108,6 +2112,7 @@ + @@ -3697,6 +3702,9 @@ ToggleSwitch_IsOn.xaml + + XamlGlobalResources.xaml + diff --git a/src/SamplesApp/UITests.Shared/Windows_UI_Xaml/Resources/XamlGlobalResources.xaml b/src/SamplesApp/UITests.Shared/Windows_UI_Xaml/Resources/XamlGlobalResources.xaml new file mode 100644 index 000000000000..88b38fe11dd5 --- /dev/null +++ b/src/SamplesApp/UITests.Shared/Windows_UI_Xaml/Resources/XamlGlobalResources.xaml @@ -0,0 +1,27 @@ + + + + + This text should be rendered in PINK with a PINK border around it. + + + + diff --git a/src/SamplesApp/UITests.Shared/Windows_UI_Xaml/Resources/XamlGlobalResources.xaml.cs b/src/SamplesApp/UITests.Shared/Windows_UI_Xaml/Resources/XamlGlobalResources.xaml.cs new file mode 100644 index 000000000000..651bae318d7d --- /dev/null +++ b/src/SamplesApp/UITests.Shared/Windows_UI_Xaml/Resources/XamlGlobalResources.xaml.cs @@ -0,0 +1,16 @@ +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Documents; +using Uno.UI.Samples.Controls; + +namespace UITests.Shared.Windows_UI_Xaml.Resources +{ + [SampleControlInfo("XAML", "XamlGlobalResources", description: "Using a resource defined in Global.Xaml's Resources (Pink).")] + public sealed partial class XamlGlobalResources : Page + { + public XamlGlobalResources() + { + this.InitializeComponent(); + } + } +} diff --git a/src/Uno.UI/FeatureConfiguration.cs b/src/Uno.UI/FeatureConfiguration.cs index fcfd80ffe260..e06fa0fff886 100644 --- a/src/Uno.UI/FeatureConfiguration.cs +++ b/src/Uno.UI/FeatureConfiguration.cs @@ -34,6 +34,17 @@ public static class UIElement #endif } + public static class Xaml + { + /// + /// Maximal "BasedOn" recursive resoling depth. + /// + /// + /// This is a mechanism to prevent hard-to-diagnose stack overflow when a resource name is not found. + /// + public static int MaxRecursiveResolvingDepth { get; set; } = 12; + } + public static class FrameworkElement { /// diff --git a/src/Uno.UI/UI/Xaml/Markup/Reader/XamlObjectBuilder.cs b/src/Uno.UI/UI/Xaml/Markup/Reader/XamlObjectBuilder.cs index 6ac334f428bf..5ef45059cf0c 100644 --- a/src/Uno.UI/UI/Xaml/Markup/Reader/XamlObjectBuilder.cs +++ b/src/Uno.UI/UI/Xaml/Markup/Reader/XamlObjectBuilder.cs @@ -271,7 +271,7 @@ private void ProcessNamedMember(XamlObjectDefinition control, object instance, X } else if (member.Member.DeclaringType == null && member.Member.Name == "Name") { - // This is a special case, where the declaring type is from the x: namespace, + // This is a special case, where the declaring type is from the x: namespace, // but is considered of an unknown type. This can happen when providing the // name of a control using x:Name instead of Name. if (TypeResolver.GetPropertyByName(control.Type, "Name") is PropertyInfo nameInfo) @@ -466,6 +466,11 @@ void ResolveResource() _postActions.Enqueue(ResolveResource); } + else + { + // Here we assigned a {StaticResource} on a standard property (not a DependencyProperty) + // We can't resolve it. + } } } diff --git a/src/Uno.UI/UI/Xaml/Markup/Reader/XamlObjectDefinition.cs b/src/Uno.UI/UI/Xaml/Markup/Reader/XamlObjectDefinition.cs index 75e0dccfe8ad..46c1e12d4716 100644 --- a/src/Uno.UI/UI/Xaml/Markup/Reader/XamlObjectDefinition.cs +++ b/src/Uno.UI/UI/Xaml/Markup/Reader/XamlObjectDefinition.cs @@ -9,35 +9,33 @@ namespace Windows.UI.Xaml.Markup.Reader { #if DEBUG - [DebuggerDisplay("Type: {_type.Name}")] + [DebuggerDisplay("Type: {Type.Name}")] #endif - internal class XamlObjectDefinition + internal class XamlObjectDefinition { - private XamlType _type; - public XamlObjectDefinition(XamlType type, int lineNumber, int linePosition, XamlObjectDefinition owner) { LineNumber = lineNumber; LinePosition = linePosition; - _type = type; + Type = type; Owner = owner; Members = new List(); Objects = new List(); } - public XamlType Type { get { return _type; } } + public XamlType Type { get; } - public List Members { get; private set; } + public List Members { get; } - public List Objects { get; private set; } + public List Objects { get; } public object Value { get; set; } - public int LineNumber { get; private set; } + public int LineNumber { get; } public int LinePosition { get; set; } - public XamlObjectDefinition Owner { get; private set; } + public XamlObjectDefinition Owner { get; } } } diff --git a/src/Uno.UI/UI/Xaml/ResourceDictionary.cs b/src/Uno.UI/UI/Xaml/ResourceDictionary.cs index 3eacc376d5f0..0963628b0d89 100644 --- a/src/Uno.UI/UI/Xaml/ResourceDictionary.cs +++ b/src/Uno.UI/UI/Xaml/ResourceDictionary.cs @@ -1,15 +1,14 @@ using System; using System.Collections.Generic; -using System.Runtime.InteropServices; -using Windows.Foundation; -using Windows.Foundation.Collections; -using Windows.Foundation.Metadata; +using System.Threading; +using Uno.UI; + namespace Windows.UI.Xaml { public partial class ResourceDictionary : DependencyObject { - private Dictionary _values = new Dictionary(); - private bool _isResolving = false; + private readonly Dictionary _values = new Dictionary(); + private int _resolvingDepth = 0; public ResourceDictionary() { @@ -69,18 +68,19 @@ public bool TryGetValue(object key, out object value) { try { - if (!_isResolving) + _resolvingDepth++; + + if (_resolvingDepth <= FeatureConfiguration.Xaml.MaxRecursiveResolvingDepth) { // This prevents a stack overflow while looking for a // missing resource in generated xaml code. - _isResolving = true; value = DefaultResolver?.Invoke(key.ToString()); } } finally { - _isResolving = false; + _resolvingDepth--; } return value != null; @@ -102,26 +102,12 @@ public object this[object key] return value; } - set - { - _values[key] = value; - } + set => _values[key] = value; } - public global::System.Collections.Generic.ICollection Keys - { - get - { - return _values.Keys; - } - } - public global::System.Collections.Generic.ICollection Values - { - get - { - return _values.Values; - } - } + public global::System.Collections.Generic.ICollection Keys => _values.Keys; + + public global::System.Collections.Generic.ICollection Values => _values.Values; public void Add(global::System.Collections.Generic.KeyValuePair item) => _values.Add(item.Key.ToString(), item.Value);