Search code examples
uwpuwp-xamlacrylic-material

UWP Is there a way to disable Acrylic for the entire app and use the fallback color always?


Im currently working on a UWP app that looks something like this with Acrylic on the left panel: A picture of my app

Now when I enable power saving mode on my laptop, the acrylic gets replaced with its fallback color:

Power saving pic

Now I want an option in my app's settings screen to disable acrylic throughout the app, and have the fallback color be used always. Im not sure where to begin however. This seems promising but I'm not sure how I'd implement it without having to go through every single acrylic material in the app and add code to disable it.

Is there a top level setting that I could use to do this? Thanks.


Solution

  • You can use CustomResource to decide how to display your AcrylicBrush:

    Prepare

    In the question description, you need a top-level setting to switch the Acrylic effect. Here you can use LocalSettings.

    Tool.cs

    public class Tool
    {
        public static void WriteLocalSetting(string key, object value)
        {
            var localSetting = ApplicationData.Current.LocalSettings;
            localSetting.Values[key.ToString()] = value;
        }
        public static object GetLocalSetting(string key, object defaultValue)
        {
            var localSetting = ApplicationData.Current.LocalSettings;
            bool isKeyExist = localSetting.Values.ContainsKey(key.ToString());
            if (isKeyExist)
            {
                return localSetting.Values[key.ToString()];
            }
            else
            {
                WriteLocalSetting(key, defaultValue);
                return defaultValue;
            }
        }
    }
    

    Ddefine

    According to the documentation of CustomResource, you need to create a derived class.

    public class CustomResourceLoader : CustomXamlResourceLoader
    {
        protected override object GetResource(string resourceId, string objectType, string propertyName, string propertyType)
        {
            if (resourceId == "MyBackground")
            {
                bool isUseAcrylic = (bool)Tool.GetLocalSetting("IsUseAcrylic", true);
                var brush = new AcrylicBrush();
                brush.TintColor = Colors.White;
                brush.BackgroundSource = AcrylicBackgroundSource.HostBackdrop;
                brush.TintOpacity = 0.7;
                brush.FallbackColor = Colors.White;
                brush.AlwaysUseFallback = !isUseAcrylic;
                return brush;
            }
            return null;
        }
    }
    

    Usage

    App.xaml.cs

    public App()
    {
        // ...
        CustomXamlResourceLoader.Current = new CustomResourceLoader();
    }
    

    MainPage

    <Grid Background="{CustomResource MyBackground}">
        <ToggleSwitch Toggled="ToggleSwitch_Toggled"/>
    </Grid>
    
    private void ToggleSwitch_Toggled(object sender, RoutedEventArgs e)
    {
        Tool.WriteLocalSetting("IsUseAcrylic", (sender as ToggleSwitch).IsOn);
        // Need Re-render
    }
    

    It should be noted that switching at runtime will not affect the already rendered elements. After the modification, you can pop up a MessageDialog asking the user to restart the application to re-render.

    Thanks.