Skip to content

Commit 06609d6

Browse files
committed
fix(xamlreader): Load ThemeResources properly
This change ensures that ThemeResources are loaded through the common flow for resource loading, so that the values coming from actual theme dictionaries, and parent element lazy dictionaries are applied properly.
1 parent af4f1d6 commit 06609d6

File tree

4 files changed

+114
-15
lines changed

4 files changed

+114
-15
lines changed

src/Uno.UI.Tests/Windows_UI_Xaml_Markup/XamlReaderTests/Given_XamlReader.cs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,64 @@ public void When_StaticResource()
240240
app.Resources.Remove("StaticHeight");
241241
}
242242

243+
[TestMethod]
244+
public void When_ThemeResource()
245+
{
246+
var app = UnitTestsApp.App.EnsureApplication();
247+
248+
if (app.Resources.ThemeDictionaries.TryGetValue("Light", out var themeDictionary)
249+
&& themeDictionary is ResourceDictionary dictionary)
250+
{
251+
dictionary["StaticRow"] = 42;
252+
dictionary["StaticWidth"] = 42.0;
253+
dictionary["StaticHeight"] = 44.0;
254+
}
255+
256+
var s = GetContent(nameof(When_ThemeResource));
257+
var r = Windows.UI.Xaml.Markup.XamlReader.Load(s) as UserControl;
258+
259+
Assert.IsNotNull(r);
260+
261+
var panel = r.FindName("innerPanel") as StackPanel;
262+
Assert.IsNotNull(panel);
263+
264+
Assert.AreEqual(42, Grid.GetRow(panel));
265+
Assert.AreEqual(42.0, panel.Width);
266+
Assert.AreEqual(44.0, panel.Height);
267+
268+
if (app.Resources.ThemeDictionaries.TryGetValue("Light", out var themeDictionary2)
269+
&& themeDictionary is ResourceDictionary dictionary2)
270+
{
271+
dictionary2.Remove("StaticRow");
272+
dictionary2.Remove("StaticWidth");
273+
dictionary2.Remove("StaticHeight");
274+
}
275+
}
276+
277+
[TestMethod]
278+
public void When_ThemeResource_Lazy()
279+
{
280+
var app = UnitTestsApp.App.EnsureApplication();
281+
282+
var s = GetContent(nameof(When_ThemeResource_Lazy));
283+
var r = Windows.UI.Xaml.Markup.XamlReader.Load(s) as UserControl;
284+
285+
Assert.IsNotNull(r);
286+
287+
var panel = r.FindName("innerPanel") as StackPanel;
288+
Assert.IsNotNull(panel);
289+
290+
Assert.AreEqual(0, Grid.GetRow(panel));
291+
Assert.AreEqual(double.NaN, panel.Width);
292+
Assert.AreEqual(double.NaN, panel.Height);
293+
294+
r.ForceLoaded();
295+
296+
Assert.AreEqual(42, Grid.GetRow(panel));
297+
Assert.AreEqual(42.0, panel.Width);
298+
Assert.AreEqual(44.0, panel.Height);
299+
}
300+
243301
[TestMethod]
244302
public void When_TextBlock_Basic()
245303
{
@@ -306,6 +364,8 @@ public void When_Style_ControlTemplate()
306364
var r = Windows.UI.Xaml.Markup.XamlReader.Load(s) as UserControl;
307365
Assert.IsNotNull(r);
308366

367+
r.ForceLoaded();
368+
309369
var innerContent = r.Content as ContentControl;
310370
Assert.IsNotNull(innerContent);
311371

@@ -587,6 +647,8 @@ public void When_StaticResource_Style_And_Binding()
587647
var s = GetContent(nameof(When_StaticResource_Style_And_Binding));
588648
var r = Windows.UI.Xaml.Markup.XamlReader.Load(s) as UserControl;
589649

650+
r.ForceLoaded();
651+
590652
Assert.IsTrue(r.Resources.ContainsKey("test"));
591653

592654
var tb1 = r.FindName("tb1") as ToggleButton;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
2+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
3+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
4+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
5+
xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
6+
Name="rootPage"
7+
mc:Ignorable="d">
8+
9+
<StackPanel x:Name="innerPanel"
10+
Width="{ThemeResource StaticWidth}"
11+
Height="{ThemeResource StaticHeight}"
12+
Grid.Row="{ThemeResource StaticRow}" />
13+
</Page>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
2+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
3+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
4+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
5+
xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
6+
Name="rootPage"
7+
mc:Ignorable="d">
8+
9+
<Page.Resources>
10+
<x:Double x:Key="StaticWidth">42.0</x:Double>
11+
<x:Double x:Key="StaticHeight">44.0</x:Double>
12+
<x:Int32 x:Key="StaticRow">42</x:Int32>
13+
</Page.Resources>
14+
15+
<StackPanel x:Name="innerPanel"
16+
Width="{ThemeResource StaticWidth}"
17+
Height="{ThemeResource StaticHeight}"
18+
Grid.Row="{ThemeResource StaticRow}" />
19+
</Page>

src/Uno.UI/UI/Xaml/Markup/Reader/XamlObjectBuilder.cs

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System.Text.RegularExpressions;
88
using Uno.Extensions;
99
using Uno.UI;
10+
using Uno.UI.Xaml;
1011
using Uno.Xaml;
1112
using Windows.UI.Xaml.Controls;
1213
using Windows.UI.Xaml.Data;
@@ -453,7 +454,7 @@ private void ProcessMemberMarkupExtension(object instance, XamlMemberDefinition
453454
{
454455
ProcessBindingMarkupNode(instance, member);
455456
}
456-
else if (IsStaticResourceMarkupNode(member))
457+
else if (IsStaticResourceMarkupNode(member) || IsThemeResourceMarkupNode(member))
457458
{
458459
ProcessStaticResourceMarkupNode(instance, member);
459460
}
@@ -465,25 +466,26 @@ private void ProcessStaticResourceMarkupNode(object instance, XamlMemberDefiniti
465466

466467
if (resourceNode != null)
467468
{
468-
string keyName = resourceNode.Members.FirstOrDefault()?.Value?.ToString();
469+
var keyName = resourceNode.Members.FirstOrDefault()?.Value?.ToString();
469470
var dependencyProperty = TypeResolver.FindDependencyProperty(member);
470471

471-
if (keyName != null && dependencyProperty != null)
472+
if (keyName != null
473+
&& dependencyProperty != null
474+
&& instance is DependencyObject dependencyObject)
472475
{
473-
void ResolveResource()
474-
{
475-
object staticResource = ResolveStaticResource(instance, keyName);
476+
ResourceResolver.ApplyResource(
477+
dependencyObject,
478+
dependencyProperty,
479+
keyName,
480+
isThemeResourceExtension: IsThemeResourceMarkupNode(member));
476481

477-
if (staticResource != null)
482+
if (instance is FrameworkElement fe)
483+
{
484+
fe.Loading += delegate
478485
{
479-
instance.SetValue(
480-
dependencyProperty,
481-
staticResource
482-
);
483-
}
486+
fe.UpdateResourceBindings();
487+
};
484488
}
485-
486-
_postActions.Enqueue(ResolveResource);
487489
}
488490
else
489491
{
@@ -513,7 +515,10 @@ private static object ResolveStaticResource(object instance, string keyName)
513515
}
514516

515517
private bool IsStaticResourceMarkupNode(XamlMemberDefinition member)
516-
=> member.Objects.Any(o => o.Type.Name == "StaticResource" || o.Type.Name == "ThemeResource");
518+
=> member.Objects.Any(o => o.Type.Name == "StaticResource");
519+
520+
private bool IsThemeResourceMarkupNode(XamlMemberDefinition member)
521+
=> member.Objects.Any(o => o.Type.Name == "ThemeResource");
517522

518523
private void ProcessBindingMarkupNode(object instance, XamlMemberDefinition member)
519524
{

0 commit comments

Comments
 (0)