Skip to content

Commit

Permalink
[C] Propagate resources when reparenting
Browse files Browse the repository at this point in the history
- fixes a bug when the theme is changed while the control/page isn't
  parented. Should fix @LeDahu22 reported issue of #21744
  • Loading branch information
StephaneDelcroix committed Apr 17, 2024
1 parent df8aa54 commit 5c93b56
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 3 deletions.
4 changes: 2 additions & 2 deletions src/Controls/src/Core/Application/Application.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ public Page? MainPage

if (value is not null)
{
OnParentResourcesChanged(this.GetMergedResources());
OnParentResourcesChanged([new KeyValuePair<string, object>(AppThemeBinding.AppThemeResource, _lastAppTheme)]);
value.OnResourcesChanged(this.GetMergedResources());
value.OnResourcesChanged([new KeyValuePair<string, object>(AppThemeBinding.AppThemeResource, _lastAppTheme)]);
((IElementDefinition)this).AddResourcesChangedListener(value.OnParentResourcesChanged);
}

Expand Down
5 changes: 4 additions & 1 deletion src/Controls/src/Core/Element/Element.cs
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ internal Element ParentOverride
/// <inheritdoc/>
void IElementDefinition.AddResourcesChangedListener(Action<object, ResourcesChangedEventArgs> onchanged)
{
_changeHandlers = _changeHandlers ?? new List<Action<object, ResourcesChangedEventArgs>>(2);
_changeHandlers ??= new List<Action<object, ResourcesChangedEventArgs>>(2);
_changeHandlers.Add(onchanged);
}

Expand Down Expand Up @@ -354,6 +354,9 @@ void SetParent(Element value)
if (RealParent != null)
{
OnParentResourcesChanged(RealParent.GetMergedResources());
if (Application.Current?.RequestedTheme != ApplicationModel.AppTheme.Unspecified)
OnParentResourcesChanged([new KeyValuePair<string, object>(AppThemeBinding.AppThemeResource, Application.Current.RequestedTheme)]);

((IElementDefinition)RealParent).AddResourcesChangedListener(OnParentResourcesChanged);
}

Expand Down
9 changes: 9 additions & 0 deletions src/Controls/tests/Xaml.UnitTests/Issues/Maui21774.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Microsoft.Maui.Controls.Xaml.UnitTests.Maui21774">
<StackLayout>
<Label x:Name="label0" TextColor="{DynamicResource labelColor}"/>
<Label x:Name="label1" TextColor="{AppThemeBinding Light=LimeGreen, Dark=HotPink}"/>
</StackLayout>
</ContentPage>
69 changes: 69 additions & 0 deletions src/Controls/tests/Xaml.UnitTests/Issues/Maui21774.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Maui.ApplicationModel;
using Microsoft.Maui.Controls.Core.UnitTests;
using Microsoft.Maui.Controls.Shapes;
using Microsoft.Maui.Devices;
using Microsoft.Maui.Dispatching;

using Microsoft.Maui.Graphics;
using Microsoft.Maui.UnitTests;
using NUnit.Framework;

namespace Microsoft.Maui.Controls.Xaml.UnitTests;

public partial class Maui21774
{
public Maui21774()
{
InitializeComponent();
}

public Maui21774(bool useCompiledXaml)
{
//this stub will be replaced at compile time
}

[TestFixture]
class Test
{
[SetUp]
public void Setup()
{
Application.SetCurrentApplication(new MockApplication());
DispatcherProvider.SetCurrent(new DispatcherProviderStub());
}

[TearDown] public void TearDown() => AppInfo.SetCurrent(null);

[Test]
public void AppThemeChangeOnUnparentedPage([Values(false, true)] bool useCompiledXaml)
{
Application.Current.Resources.Add("labelColor", Colors.LimeGreen);
Application.Current.UserAppTheme = AppTheme.Light;
var page = new Maui21774(useCompiledXaml);
Application.Current.MainPage = page;

Assert.That(page.label0.TextColor, Is.EqualTo(Colors.LimeGreen));
Assert.That(page.label1.TextColor, Is.EqualTo(Colors.LimeGreen));

//unparent the page, change the resource and the theme
Application.Current.MainPage = null;
Application.Current.Resources["labelColor"] = Colors.HotPink;
Application.Current.UserAppTheme = AppTheme.Dark;
//labels should not change
Assert.That(page.label0.TextColor, Is.EqualTo(Colors.LimeGreen));
Assert.That(page.label1.TextColor, Is.EqualTo(Colors.LimeGreen));

//reparent the page
Application.Current.MainPage = page;
//labels should change
Assert.That(page.label0.TextColor, Is.EqualTo(Colors.HotPink));
Assert.That(page.label1.TextColor, Is.EqualTo(Colors.HotPink));
}
}
}

0 comments on commit 5c93b56

Please sign in to comment.