Search code examples
c#mauimaui-windows

Cannot use WeakReferenceMessenger inside MAUI windows


I tried to dynamically change the title bar color according to the user's selected theme in my MAUI Windows application. This is a MAUI multi-platform template, similar to Xamarin Forms. Finally, I added a ViewModel to App.xaml.cs inside the Windows project and attempted to change the color dynamically using MessagingCenter. this worked, but it has been deprecated. So I switched to WeakReferenceMessenger, but it is throwing an exception.

InnerException

{"Could not load file or assembly 'WinRT.Runtime, Version=2.1.0.0, Culture=neutral, PublicKeyToken=99ea127f02d97709'. The system cannot find the file specified.":"WinRT.Runtime, Version=2.1.0.0, Culture=neutral, PublicKeyToken=99ea127f02d97709"} System.Exception {System.IO.FileNotFoundException}

Message

"The type initializer for '<Module>' threw an exception." string

enter image description here

App.xaml.cs (Inside Windows project)

using Microsoft.UI.Xaml;

namespace XX.WinUI;

public partial class App : MauiWinUIApplication
{
    public App()
    {
        this.InitializeComponent();
    }

    protected override void OnLaunched(LaunchActivatedEventArgs args)
    {
        base.OnLaunched(args);
        this.Resources["AppViewModel"] = new AppViewModel();
    }

    protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
}

ViewModel(Inside Windows project)

   public partial class AppViewModel : INotifyPropertyChanged
    {
        private string _titleBarColor;
        private string _titleColor;

        public string TitleBarColor
        {
            get => _titleBarColor;
            set
            {
                if (_titleBarColor != value)
                {
                    _titleBarColor = value;
                    OnPropertyChanged();
                }
            }
        }

        public string TitleColor
        {
            get => _titleColor;
            set
            {
                if (_titleColor != value)
                {
                    _titleColor = value;
                    OnPropertyChanged();
                }
            }
        }

        public AppViewModel()
        {

            WeakReferenceMessenger.Default.Register<WeakReferenceMessage>(this, (r, m) =>
{
});
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }


   public class WeakReferenceMessage : ValueChangedMessage<TitleBarModel>
   {
       public WeakReferenceMessage(TitleBarModel value) : base(value)
       {
       }
   }

(Inside Windows project) This method is inside UWPPhoneFeatureService which is the native custom renderer.

public void ChangeDeviceStatusBarColor()
  {
      TitleBarModel titleBarModel = new TitleBarModel();
      string themeCode = GetAppSetting("ColorTheme");
      Windows.UI.Color col;
      switch (themeCode)
      {
          case "theme-black":
              col = ConvertColor(38, 33, 61);
              titleBarModel.TitleColor = "#FFFFFF";
              break;

          case "theme-monaco":
              col = ConvertColor(124, 147, 131);
              titleBarModel.TitleColor = "#FFFFFF";
              break;

          default:
              col = ConvertColor(1, 179, 239);
              titleBarModel.TitleColor = "#FFFFFF";
              break;
      }

      titleBarModel.TitleBarColor = AppSettingKey.statusBarColor = $"#{col.R:X2}{col.G:X2}{col.B:X2}";

      WeakReferenceMessenger.Default.Send(new WeakReferenceMessage(titleBarModel));
 
  }

Windows side

public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder.UseSharedMauiApp();
        builder.UseMauiCommunityToolkit();
        builder.UseMauiCameraView();
        builder.ConfigureMauiHandlers(handlers =>
        {
            handlers.AddHandler(typeof(FormsWebView), typeof(FormsWebViewRenderer));
        });
        builder.Services.AddSingleton<IPhoneFeatureService, UWPPhoneFeatureService>();
        return builder.Build();
    }
}

Solution

  • I had the same problem. It seems like CommunityToolkit.Mvvm version 8.3.0 causes the issue. Try downgrading CommunityToolkit.Mvvm to 8.2.2. The 8.3.0 just came the same day you posted.