Search code examples
c#winui-3comexceptionwinui-xaml

WinUI Color-changing while process is running


when I try to change the color of my GradientStop in my xaml for my winui 3 app from the codebehind while the app is running, it throws 'System.Runtime.InteropServices.COMException in WinRT.Runtime.dll'. It only happens the second time I try to change the color, the first time when the program launches, it works. I change my app theme in settings while the app is running, so it launches the event from Windows.UI.ViewManagement.UISettings. I am running WinUI 3 app unpackaged. with WindowsAppSDKIncluded true in the csproj file. Can anybody tell me what this exception even means or a solution to it? I have no idea what the output even means.

Here is my Code:

MainWindow.xaml.cs:

public sealed partial class Window : WinUIEx.WindowEx {
    private DataHandler handler;
    private bool isThemeSystem = true;
    ...
}
public Window() {
    handler = new DataHandler();
}
private Windows.UI.Color dyn(string name) {
    return handler.getColor(currentTheme, name);
}

public void setTheme()
{
    if (isThemeSystem)
    {
        try
        {
            currentTheme = Convert.ToInt32(Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize").GetValue("AppsUseLightTheme"));

            gradient0.Color = dyn("gr0");
            gradient1.Color = dyn("gr1");
        } catch (Exception ex) {
            Debug.WriteLine(ex.StackTrace);
        }
    } 
    else
    {
        
    }
}

DataHandler.cs:

using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Xml;
using System.Xml.Linq;
using Windows.UI;

namespace Hostware
{
    internal class DataHandler
    {
        public static string appData = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Hostware");
        private static Dictionary<string, string> list = new Dictionary<string, string>()
        {
            {"l_gr0","#FFFFFF"},
            {"l_gr1","#FFA9A9A9"},
            {"d_gr0","#101010"},
            {"d_gr1","#292929"},
        };

        //private SolidColorBrush

        public DataHandler()
        {
            Debug.WriteLine("Initialized Hostware/DataHandler.cs");

            //app data
            Directory.CreateDirectory(appData);

            //app functionality


        }

        public Windows.UI.Color getColor(int themeInt, string name)
        {
            string extender = string.Empty;
            if (themeInt == 0)
            {
                //dark
                extender = "d_";
            }
            else if (themeInt == 1)
            {
                extender = "l_";
            }
            System.Drawing.Color color = System.Drawing.ColorTranslator.FromHtml(list.GetValueOrDefault(extender + name));
            int r = color.R;
            int g = color.G;
            int b = color.B;
            return Windows.UI.Color.FromArgb(255,(byte) r, (byte) g, (byte) b);
        }
    }
}

The output it receives:

[![][1]][1]

I tried first using App.Xaml resources, but though the error was from it trying to read a precompiled asset. so I switched it over to my DataHandler.cs file but it still gives the same error.

EDIT: DO NOT USE UISettings.ColorValuesChanged to detect personalization settings changing, IT WILL RESULT IN AN UNFIXABLE EXCEPTION


Solution

  • I found the answer myself, therefore this is closed, If you are using an unpackaged app (WinRT) UISettings.ColorValuesChanged will not be able to read resources from your app, it is more recommended to just restart the app.