.Net Maui: How to read/write (get/set) a global object from any content page (MVVM)

Viewed 262

I'm sure that I'm missing some deep or obvious concept here :)

So I have a page now that can setup various Bluetooth sensors and get data from a heart rate monitor, speedometer and cadence sensor. (Using Plugin.BLE)

So I do all of that in a ViewModel for a ContentPage called BluetoothPage.

I want to display the data I get in a different ContentPage called DisplayPage.

I have created a simple class (model) that can hold the data I want:

namespace TSDZ2Monitor.Models;

public partial class BluetoothData : ObservableObject
{
  //Heart rate raw data
  public int HRM { get; set; }
  public double HRR { get; set; }

  //SPD raw data
  public int SPDWheelRevolutions { get; set; }
  public double SPDWheelEventTime { get; set; }

  //CAD raw data
  public int CADCrankRevolutions { get; set; }
  public double CADCrankEventTime { get; set; }

}

So, how do I get the data from my Bluetooth page to my Display page?

I suspect I need to use an object based on my model and populate it with data in my Bluetooth viewmodel (easy...ish)?

But how can my Display page see this data as it happens?

When I tried working with ReactNative this sort of thing was a nightmare (State!)

Or am I being a bit simple in the head here :lol

Workaround: I could save the data to some local storage or sqlite as per https://docs.microsoft.com/en-us/learn/dotnet-maui/store-local-data/2-compare-storage-options - is that the way to do it, or can it be done with the object?

G.

Edit: I think I could also use the MessagingService https://docs.microsoft.com/en-us/dotnet/maui/fundamentals/messagingcenter and https://codemilltech.com/messing-with-xamarin-forms-messaging-center/ if I can figure out how to use them in MVVM context.

Also What is the difference between using MessagingCenter and standard .NET event handlers for informing interested parties of changes?

1 Answers

So it seems that using the MessagingCenter was a way to go.

Following the guidance in https://codemilltech.com/messing-with-xamarin-forms-messaging-center/

I created a MessagingMarker class:

namespace TSDZ2Monitor.Classes;

public class MessagingMarker
{
}

That's all.

In the ViewModel where I wanted to send an object from, I did

MessagingCenter.Send(new MessagingMarker(), "BTDataUpdate", btd);

where btd was an instance of a class I created to hold my data: Here is a simplified model:

namespace TSDZ2Monitor.Models;

public partial class BluetoothData : ObservableObject
{
  //Heart rate raw data
  private int hRM;
  public int HRM  //heart rate
  {
    get => hRM;
    set => SetProperty(ref hRM, value);
  }
  private double hRR; //heartrate R-R value
  public double HRR
  {
    get => hRR;
    set => SetProperty(ref hRR, value);
  }

  private double wheelRPM;
  public double WheelRPM
  {
    get => wheelRPM;
    set => SetProperty(ref wheelRPM, value);
  }

  private double cadence;
  public double Cadence
  {
    get => cadence;
    set => SetProperty(ref cadence, value);
  }

}

In the constructor of the ViewModel for the sending page (probably best somewhere else?)

 public BluetoothData btd = new();

This is not used in the XAML for this ViewModel

In my receiving ViewModel

I also created an instance of the BluetoothData class, but this is used in the XAML bindings

  [ObservableProperty]
  private BluetoothData bTData;

and in the constructor of the ViewModel I had

    BTData = new BluetoothData();

    MessagingCenter.Subscribe<MessagingMarker, BluetoothData>(this, "BTDataUpdate", (sender, arg) =>
    {
      //Debug.WriteLine($"Message received {arg}");
      BTData.HRM                   = arg.HRM;
      BTData.HRR                   = arg.HRR;
      BTData.WheelRPM              = arg.WheelRPM;
      BTData.Cadence               = arg.Cadence;
    });

Well it works, don't know what the impact on performance might be, but it seems pretty responsive.

To my way of thinking though a more idea solution is to create a global instance of any class that any ViewModel can access.

Related