我正在开发一个 .NET MAUI 应用程序,其中通过 Community.Toolkit.MVVM nuget 包使用 MVVM 模式。在下面的代码中,在 MorePage 上,我尝试将标题绑定到 Forecast.Name,这是 MorePageViewModel 的一个可观察属性,它被设置为 MorePage 本身的绑定上下文。我已经验证导航函数是通过传递正确的对象来执行的,因此问题似乎出在 MorePageViewModel 或 MorePage.xaml(.cs) 中,但我不确定在哪里。
namespace forecAstIng.Model
{
public abstract class TimeSeriesData
{
public string Name { get; set; }
public char MeasurementUnit { get; set; }
public double HourTimeInterval { get; set; } = 24;
public double DayTimeInterval => HourTimeInterval / 24;
public double MinuteTimeInterval => HourTimeInterval * 60;
public List<double> ValueHistory { get; set; }
public List<double> ValuePredictions { get; set; }
public double HistoryHigh { get; set; }
public double HistoryLow { get; set; }
public string CurrentBehaviour { get; set; }
public double CurrentValue { get; set; }
}
class WeatherData : TimeSeriesData
{
}
class StockData : TimeSeriesData
{
}
}
using forecAstIng.View;
namespace forecAstIng.ViewModel
{
public partial class ForecastsViewModel : BaseViewModel
{
public ObservableCollection<TimeSeriesData> Forecasts { get; } = new();
public ForecastsViewModel()
{
Title = "forecAstIng";
Forecasts.Add(new WeatherData { Name = "Prague, CZ", CurrentBehaviour = "sunny", CurrentValue = 23.8776575, HistoryHigh = 27.389, HistoryLow = 20, MeasurementUnit = 'C' });
}
[RelayCommand]
async Task GoToMorePage(TimeSeriesData forecast)
{
if (forecast is null)
return;
await Shell.Current.GoToAsync(nameof(MorePage), true, new Dictionary<string, object>
{
{"Forecast", forecast}
});
}
}
}
namespace forecAstIng.ViewModel
{
[QueryProperty(nameof(TimeSeriesData), "Forecast")]
public partial class MorePageViewModel : BaseViewModel
{
public MorePageViewModel()
{
}
[ObservableProperty]
TimeSeriesData forecast;
}
}
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage x:Class="forecAstIng.View.MorePage"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:model="clr-namespace:forecAstIng.Model"
xmlns:viewmodel="clr-namespace:forecAstIng.ViewModel"
x:DataType="viewmodel:MorePageViewModel"
Title="{Binding Forecast.Name}"
BackgroundColor="#402E7A">
</ContentPage>
namespace forecAstIng.View
{
public partial class MorePage : ContentPage
{
public MorePage(MorePageViewModel vm)
{
InitializeComponent();
BindingContext = vm;
}
}
}
路线在 AppShell 中注册,并在 MauiProgram.cs 中添加瞬态服务
更多页面上的标题完全是空白。
没有成功,我尝试更改属性名称、可访问性、在 MorePage.xaml 文件和导航功能中随处用作属性名称的“预测”名称,以及自动生成的 nuget 包的名称支持场。我曾经实现了预期的行为,但后来我改变了一些东西,并且不确定我做了什么不同的事情。
您混淆了查询属性和基于对象的导航数据。查询属性只能是原始数据类型(
int
、bool
、...)和 string
。
现在,您将通过基于对象的导航传递
Forecast
参数,方法如下:
await Shell.Current.GoToAsync(nameof(MorePage), true, new Dictionary<string, object>
{
{"Forecast", forecast}
});
这实际上将
Dictionary<string, object>
传递给 ViewModel,并要求您实现一个 接收方法来处理导航数据,更具体地说,您的 ViewModel 需要实现 IQueryAttributable
接口:
namespace forecAstIng.ViewModel
{
public partial class MorePageViewModel : IQueryAttributable, BaseViewModel
{
[ObservableProperty]
TimeSeriesData forecast;
}
public void ApplyQueryAttributes(IDictionary<string, object> query)
{
Forecast = query["Forecast"] as TimeSeriesData;
}
}
旁注:
[QueryProperty(nameof(TimeSeriesData), "Forecast")]
无论如何都不起作用,因为它应该是[QueryProperty(nameof(Forecast), "Forecast")]
,QueryProperty
属性的参数之一是属性的名称,另一个是查询参数的名称。您传递的是类型的名称,而不是属性。然而,这并不能解决您的问题,我只是为了完整起见才提到这一点。