Xamarin Forms Load Resources on startup

2019-08-23 07:51发布

I have an Xamarin Forms app with MvvmCross for Android and IOS and I would like to add a dark theme. My idea was to have to dictionaries with the ressources for either the dark or the light theme and load the one I need on startup.

I added this after I registered the dependencies in my MvxApplication:

        if (Mvx.IoCProvider.Resolve<ISettingsManager>().Theme == AppTheme.Dark)
        {
            Application.Current.Resources.Add(new ColorsDark());
        }
        else
        {
            Application.Current.Resources.Add(new ColorsLight());
        }

ColorsDark and ColorsLight are my ResourceDictionary. After that i can see the new Dictionary under Application.Current.Resources.MergedDictionaries but the controls can't find the resources as it seems. However it does work when I add it to the App.xaml

      <ResourceDictionary Source="Style/ColorsDark.xaml" />

Do I have to put move that another part in the code or is that a wrong approach at all?

2条回答
Explosion°爆炸
2楼-- · 2019-08-23 08:26

If you want something to load up when your app loads then you have to code it in App.xaml.cs

protected override void OnStart ()
    {
        if (Mvx.IoCProvider.Resolve<ISettingsManager>().Theme == AppTheme.Dark)
        {
            Application.Current.Resources.Add(new Xamarin.Forms.Style(typeof(ContentPage))
            {
                ApplyToDerivedTypes = true,
                Setters = {
                new Xamarin.Forms.Setter { Property = ContentPage.BackgroundImageProperty, Value = "bkg7.png"},
            }
            });
        }
        else
        {
            Application.Current.Resources.Add(new Xamarin.Forms.Style(typeof(ContentPage))
            {
                ApplyToDerivedTypes = true,
                Setters = {
                new Xamarin.Forms.Setter { Property = ContentPage.BackgroundImageProperty, Value = "bkg7.png"},
            }
            });
        }
    }

In this code I'm setting the BackgroungImage of all of my pages. Hope you'll get the idea from this code.

查看更多
唯我独甜
3楼-- · 2019-08-23 08:33

Personally don't like this approach at all. What i do: have a static class with all the colors, sizes etc. defined in static fields. At app startup or at app reload after changing skin just call ex: UiSettings.Init() for this ui definitions static class, like follows:

public static class UiSettings
{       
      public static Init()
      {
            if (Settings.AppSettings.Skin=="butterfly")
            {
             ColorButton = Color.Blue;
             TitleSize= 12.0;
            }
            else
            if (Settings.AppSettings.Skin=="yammy")
            {
             ColorButton = Color.Red;
             if (Core.IsAndroid)
                ButtonsMargin = new Thickness(0.5,0.6,0.7,0.8);
            }
            // else just use default unmodified field default values 
        }

        public static Color ColorButton = Color.Green;
        public static Thickness ButtonsMargin = new Thickness(0.3,0.3,0.2,0.2);
        public static double TitleSize= 14.0;

}

in XAML use example:

 Color= "{x:Static xam:UiSettings.ColorProgressBack}"

in code use example:

Color = UiSettings.ColorProgressBack;

UPDATE: Remember that if you access a static class from different assemblies it is possible that you will access a fresh copy of it with default values where Init() didn't happen, if you face such case call Init() from this assembly too.

查看更多
登录 后发表回答