Hey folks,
I got an MVVM dotnet project using the mvvm community toolkit.
Now I am facing a situation where I have one viewmodel A which offers a user action that will modify the database and because
of this change my viewmodel B needs requery the database and update its data.
I came across events or messaging which provides me with an option for viewmodel-to-viewmodel communication, but afaik
all options only support sync function execution and no async option (but I deal with database so it must be async I think).
My current way to solve it is the following, but I am unsure if this is the recommended common best approach.
CommunityToolkit.Mvvm.Messaging.Messages;
public sealed class NotifyMessage : ValueChangedMessage<string>
{
public NotifyMessage(string value) : base(value) { }
}
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
public partial class ViewModelA : ObservableObject
{
public ViewModelA()
{
}
private void UpdateData()
{
// do stuff
SendMessage();
}
private void SendMessage()
{
WeakReferenceMessenger.Default.Send(new NotifyMessage("Data update in A"));
}
}
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Messaging;
using System.Diagnostics;
public partial class ViewModelB : ObservableObject, IRecipient<NotifyMessage>, IDisposable
{
[ObservableProperty] private string _lastMessage = "B";
public ViewModelB()
{
WeakReferenceMessenger.Default.Register<NotifyMessage>(this);
}
public async void Receive(NotifyMessage message)
{
LastMessage = message.Value;
try {
await RefreshData();
}
catch (Exception e)
{
Console.WriteLine("ERROR: " + e.Message);
}
}
private async Task RefreshData()
{
await Task.Delay(1000);
Console.WriteLine(LastMessage);
}
public void Dispose()
{
WeakReferenceMessenger.Default.Unregister<NotifyMessage>(this);
}
}
In viewmodel B I have one "async void" which is bad. But I don't see how to get around that otherwise. Or do I have a architectural issue and this should not rise?
I am a bit confused because this should be a quite common problem, but I didn't found any way to solve it in a good way.