. net Maui:如何从任何内容页(MVVM)读/写(获取/设置)一个全局对象



我相信我在这里遗漏了一些深刻或明显的概念:)

所以我现在有一个页面,可以设置各种蓝牙传感器,并从心率监测器,速度计和节奏传感器获取数据。(使用Plugin.BLE)

这些都是在ContentPage的ViewModel中为BluetoothPage做的

我想显示数据,我得到一个不同的ContentPage称为DisplayPage。

我已经创建了一个简单的类(模型),可以保存我想要的数据:

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; }
}

那么,我如何从我的蓝牙页面获得数据到我的显示页面?

我怀疑我需要使用一个基于我的模型的对象,并在我的蓝牙视图模型中填充数据(容易…ish)?

但是我的显示页面如何看到这些数据发生?

当我尝试使用ReactNative时,这种事情是一场噩梦(状态!)

或者我在这里有点简单:lol

解决方案:我可以将数据保存到一些本地存储或sqlite按照https://learn.microsoft.com/en-us/learn/dotnet-maui/store-local-data/2-compare-storage-options -是这样做的,还是可以用对象完成?

g .

编辑:我想我也可以使用MessagingService https://learn.microsoft.com/en-us/dotnet/maui/fundamentals/messagingcenter和https://codemilltech.com/messing-with-xamarin-forms-messaging-center/,如果我能弄清楚如何在MVVM上下文中使用它们。

另外,使用MessagingCenter和标准的。net事件处理程序通知相关方更改有什么区别?

看来使用MessagingCenter是一种可行的方法。

遵循https://codemilltech.com/messing-with-xamarin-forms-messaging-center/

中的指导我创建了一个MessagingMarker类:
namespace TSDZ2Monitor.Classes;
public class MessagingMarker
{
}

在我想要发送对象的ViewModel中,我做了

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

,其中btd是我为保存数据而创建的类的实例:

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);
}
}

在发送页面的ViewModel的构造函数中(可能最好在其他地方?)

public BluetoothData btd = new();

在ViewModel的XAML中没有使用

In my receiving ViewModel

我还创建了一个BluetoothData类的实例,但这是XAML绑定中使用的

[ObservableProperty]
private BluetoothData bTData;

,在ViewModel的构造函数中,我有

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;
});

效果很好,不知道对性能有什么影响,但它似乎反应很快。

我的想法,虽然一个更理想的解决方案是创建一个全局实例的任何类,任何ViewModel可以访问。

我也需要这样做——在我的例子中,从多个页面引用一个ObservableCollection<State> States。分享这是另一个可能的解决方案:

我创建了一个类,ObservableCollection作为static成员,在第一次使用时填充:

public class Filter
{
...
public static ObservableCollection<State> StateSelections { get; } = new();
...
public Filter(DataService dataService) : base()
{
this.dataService = dataService;
PopulateData();
}
public async Task PopulateData()
{
// Populate the available selections
await LoadStates();
}
public async Task LoadStates()
{
if (StateSelections?.Count > 0)
return;
...
}
}

对于使用集合的每个页面,其VM都有一个对类实例的引用:

public partial class ParkListVM : BaseVM
{
...
public Filter Filter { get; set; }
...
public void PopulateData()
{
if (ParkListVM.Filter is null)
ParkListVM.Filter = new Filter(dataService);
...
}
}

并且该页有一个对用于显示的静态集合的引用:

<ContentPage
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:vm="clr-namespace:NationalParks.ViewModels"
xmlns:model="clr-namespace:NationalParks.Models"
x:DataType="vm:ParkListVM"
x:Class="NationalParks.Views.ParkListPage"
Title="{Binding Title}">
<ContentPage.Resources>
<model:Filter x:Key="Filter"/>
</ContentPage.Resources>
...
<CollectionView ItemsSource="{Binding Source={x:Static model:Filter.StateSelections}}"
SelectionMode="Multiple"
SelectedItems="{Binding SelectedStates}">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="model:State">
<VerticalStackLayout>
<Label Style="{StaticResource LabelMedium}" Text="{Binding Name}" />
</VerticalStackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
...
</ContentPage>

最新更新