Search code examples
uno-platform

Uno Platform initialize Material


I have an app that is using Material extensively. Recently there was an update to Material and looking at the documentation- they have changed how material is initialized. This is the code that I had previously added to my onLaunched method in app.xaml.cs:

this.Resources.MergedDictionaries.Add(new Uno.Material.MaterialColorPalette());
this.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri("ms-appx:///MaterialColorPaletteOverride.xaml") });
this.Resources.MergedDictionaries.Add(new Uno.Material.MaterialResources());

In looking at the updated documentation at Uno Platform Material How To

The initialization has changed to the following:

Uno.Material.Resources.Init(this, null);

I tried this and Visual Studio tells me that Resources does not exist in the namespace Uno.Material. I also looked at the sample app example and it was similar:

Uno.Material.Resources.Init(this, new ResourceDictionary { Source = new Uri("ms-appx:///MaterialColorPaletteOverride.xaml") });

Obviously it suffers from the same issue- Resources does not exist- the exact error is the method Resources does not exist in Uno.Material. I have verified the other Uno Packages are at the latest. I do have Xamarin.AndroidX.Lifecycle.LiveData installed as well. Before this update to Material- everything was working as expected. The specific update is to 1.0.0-dev.778. I have reverted to 1.0.0-dev.774 and reverted my code to the three lines I first listed- and it is working again as expected. What should I do so I can implement the new changes?


Solution

  • The Uno.Material library recently introduced a breaking change to the way the Material resources are initialized. Going forward, resource initialization should be done via XAML, similar to the way we initialize <XamlControlsResources /> for WinUI.

    The documentation is in the midst of being updated but basically you need to move the initialization to your App.xaml like so:

    <Application x:Class="Uno.Themes.Samples.App"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:material="using:Uno.Material">
    
        <Application.Resources>
            <ResourceDictionary>
                <ResourceDictionary.MergedDictionaries>
                    <!-- Load WinUI resources -->
                    <XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
    
                    <MaterialColors xmlns="using:Uno.Material"
                                    ColorPaletteOverrideSource="ms-appx:///ColorPaletteOverride.xaml" />
                    <MaterialResources xmlns="using:Uno.Material" />
    
                    <!-- Rest of your application resources .... -->
                </ResourceDictionary.MergedDictionaries>
            </ResourceDictionary>
        </Application.Resources>
    </Application>
    

    Notice the new <MaterialColors /> and <MaterialResources /> tags. Keep in mind that order is important here and MaterialColors must be initialized before MaterialResources. The ColorPaletteOverrideSource is optional, but if you are overriding the default Material colors, you would set it here to the path where your new color palette is defined.

    You can then go ahead and remove the calls to Uno.Material.Resources.Init from your App.xaml.cs.

    You can have a look at the Uno.Material example for a sample of what your app might look like using the new method of resource initialization.