Share user preferences application-wide WPF MVVM

I'm trying to develop an MVVMish WPF application and I stumbled upon a problem I haven't quite figured out what's the best way to solve it.

I have a preferences page when a user can set his username for the current session, firstname etc - the relevant Model for this is AppConfig - a Singleton where I have the properties getters and setters and I have a ConfigPageViewModel that implements INotifyPropertyChanged and RaisePropertyChanged.

I want to be able to access that data on a different window in the same project and to execute methods on the following, as in execute code in the .xaml.cs of the home page for example (which now seems as a problem too, perhaps I'll solve it by binding methods to buttons but that I'll do later).

What I'm doing at the moment is setting an _appConfig = new AppConfig() in the constructors of both of the VMs and set the AppConfig properties in the VMs and they implement RaisePropertyChanged upon setting them.

From what I understand - I don't change the AppConfig model - therefore the data is only changed in the relevant VM and is not transferred to the other VM. Is it right that the preferred MVVM technique would be to create a parent-child relationship, initialize an instance of the AppConfig on startup, and use dependency injection to pass it to the construction of every VM ? If so, how am I to pass the same instance to every ViewModel ?

What are the best approaches to solve this problem ? Thanks.

Answers 1

  • Quite easy I would say:

    1. Implement bootstrapper:

    App.xaml - delete StartUp

    App.xaml.cs :

    protected override OnStartup (StartupEventArgs e) {
      base.OnStartup(e);
      var bootstrapper = new MyBootstrapper(); // your bootstrapper class
      MyBootstrapper.Run();
    }
    
    1. For simplicity let me write some dumb code but it will give you some ideas how to do it in straightforward manner

      class MyBootstrapper{
        ConfigView _configView;
        ConfigViewModel _configViewModel;
      
        public MyBootsrapper() {
          _configView = new ConfigView;
          _configViewModel = (ConfigViewModel) _vonfigView.DataContext;
      
          _configViewModel.Save += (sender, args) => { 
            // suggesting user clicked save on the view, which generated Save event in your viewmodel
            CreateAppWiseConfig(args.Data);
           }
        }
      
        public void Run() {
          _configView.Show();
        }
      
        private void CreateAppWiseConfig( MyConfigData data) {
          // here you may create ur user classes
          // and after that use it from your bootstrapper (bad idea imho) or
          // app-controller (better one) to create all other windows
        }
      

Related Articles