I have achieved desired result with MessagingCenter, but I have got an information from reading Xamarin articles that MessagingCenter is not the preferred way to trigger 30+ events. Additional to that I have to unsubscribe from MessagingCenter after action has been done. I want to have Settings page where I would have 30+ settings that have to be changed across whole application in different views. How I can inject SettingsViewModel into other ViewModels in Xamarin.Forms application?
SettingsViewModel.cs:
namespace MessagingCenterApp.ViewModels
{
public class SettingsViewModel : BaseViewModel, ISettingsViewModel
{
public ICommand ChangeCommand { get; set; }
public SettingsViewModel()
{
Title = "Settings";
this.BoxColor = Color.Red;
this.ChangeCommand = new Command(this.ChangeColor);
}
private void ChangeColor()
{
this.BoxColor = Color.FromHex(this.BoxColorS);
MessagingCenter.Send<Object, Color>(this, "boxColor", this.BoxColor);
}
private Color _boxColor;
public Color BoxColor
{
get => _boxColor;
set
{
_boxColor = value;
this.OnPropertyChanged();
}
}
private string _boxColorS;
public string BoxColorS
{
get => Preferences.Get("BoxColor", "#17805d");
set
{
Preferences.Set("BoxColor", value);
this.ChangeColor();
this.OnSettingsChanged();
this.OnPropertyChanged();
}
}
public event EventHandler<SettingsChangedEventArgs> SettingsChanged;
private void OnSettingsChanged() => this.SettingsChanged?.Invoke(this, new SettingsChangedEventArgs(this.Settings));
public Settings Settings { get; private set; }
}
}
HomeViewModel.cs:
namespace MessagingCenterApp.ViewModels
{
public class HomeViewModel : BaseViewModel
{
public HomeViewModel()
{
this.Title = "Home";
MessagingCenter.Subscribe<Object, Color>(this, "boxColor", (sender, arg) =>
{
System.Diagnostics.Debug.WriteLine("received color = " + arg);
this.BoxColor = arg;
});
this.BoxColor = Color.Red;
this.SettingsViewModel = new SettingsViewModel();
this.SettingsViewModel.SettingsChanged += OnSettingsChanged;
}
private void OnSettingsChanged(object sender, SettingsChangedEventArgs e)
{
throw new NotImplementedException();
}
private Color _boxColor;
public Color BoxColor
{
get => _boxColor;
set
{
_boxColor = value;
OnPropertyChanged();
}
}
private ISettingsViewModel SettingsViewModel { get; }
}
}
Should I somehow do all in MainViewModel? I mean:
namespace MessagingCenterApp.ViewModels
{
public class MainViewModel : BaseViewModel
{
public MainViewModel()
{
this.SettingsViewModel = new SettingsViewModel();
this.HomeViewModel = new HomeViewModel(this.SettingsViewModel);
}
public SettingsViewModel SettingsViewModel { get; set; }
public HomeViewModel HomeViewModel { get; }
}
}
Then initialized it in AppShell? I could not get this approach working.
Important! I don't want to use any MVVM framework! Only native behaviour.