xamarin / Xamarin.Forms

Xamarin.Forms is no longer supported. Migrate your apps to .NET MAUI.
https://aka.ms/xamarin-upgrade
Other
5.62k stars 1.87k forks source link

[Bug] MergedDictionaries Source references don't update when changing themes #10583

Open TradeArcher2020 opened 4 years ago

TradeArcher2020 commented 4 years ago

Description

When you have a Theme ResourceDictionary Xaml file that gets loaded in the App.Xaml via a ResourceDictionary Source reference and that Theme file in turn references sub files, subsequent themes (following the same pattern) do not refresh the UI styles despite the use of DynamicResource.

Steps to Reproduce

  1. Create a blank Xamarin.Forms project
  2. Add 2 theme folders
  3. In each theme folder, add a ResourceDictionary to serve as the theme name (i.e. Theme1 and Theme2), then add a separate ResourceDictionary called Colors and add a reference to it inside the theme. Add a third ResourceDictionary called Styles and add a reference to it inside the theme. Make sure both themes have the same structure with difference color values.
  4. In App.Xaml add Theme1 to the MergedResourceDictionaries as the default theme for when the app starts.
  5. In MainPage.Xaml add some xaml styles to use the new styles created in the themes. Make sure they are referenced as DynamicResource.
  6. In MainPage.Xaml.cs, override OnAppearing() and add code similar to this to swap out Theme1 for Theme2: `
    var mergedDictionaries = Xamarin.Forms.Application.Current.Resources.MergedDictionaries;

        if (mergedDictionaries != null)
        {
            mergedDictionaries.Clear();
            mergedDictionaries.Add(new Theme2());
        }

    `

  7. Run the app.

Expected Behavior

You should see the colors defined in Theme2.

Actual Behavior

You still see the colors from Theme1.

Basic Information

It appears that the nested MergedDictionaries don't get refreshed when the theme is swapped out.

I have noticed that if I put all of the styles into the Theme rather than reference them as a separate file, the sample will work, but as long as I try to keep Styles.xaml as a separate file, the problem persists.

Screenshots

Spring Theme (Default Theme) showing when it should be Autumn theme: image

Autumn Theme showing if you put the styles directly inside the theme Xaml file instead of referencing them via <ResourceDictionary Source="Styles.xaml" />: image

Reproduction Link

Xamarin.Forms_ThemeExample.zip

Workaround

As mentioned above, a workaround is to put the style definitions directly into the them xaml file rather than splitting them out into a separate or multiple separate files. This is sub-optimal for organizational purposes, but will make the theme change code work. In the attached zip file project above just comment out the references in the theme files to styles.xaml and uncomment the style code in the same file and you will see the theme begin to work as you would expect it should.

However, in a perfect world, we should be able to include nested references to ResourceDictionaries in Themes so that we can better organize our theme definitions and still have those nested references get refreshed when the theme is dynamically changed.

scottcollins commented 3 years ago

I just ran into this issue yesterday. Is this something that is still on the backlog to be fixed, or with Maui coming out soon will this not be fixed?