当绑定的值发生变化时,.NET MAUI的输入框中的文本未更新
我正在尝试开发一个.NET Maui应用,用于为放疗患者进行剂量计算。
我刚起步,最初是用事件驱动的方法来开发,但后来决定还是尝试走MVVM的路径。
这是一个Windows应用。
我的问题在于,当我从导入页面返回时,患者姓名和ID的输入字段不会更新。
为了避免贴出冗长的代码,我移除了一些不必要的代码。
在内存中,我在启动时将患者姓名设为Mickey Mouse,ID设为1。
启动应用时会显示这些内容。
当我从ImportPage返回后,为了测试我手动将名字改为Peters,ID改为2,但输入字段并没有更新。
我感觉自己可能忽略了某些地方,但看不出具体是什么。
我对.NET Maui和 MVVM仍然是新手。
我的 HomePage.xaml - 在这里我把患者姓名和ID绑定到两个输入字段:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Aequus.Maui.Views.HomePage"
xmlns:controls="clr-namespace:Aequus.Maui.Views.Controls"
xmlns:vm="clr-namespace:Aequus.Maui.ViewModels"
x:DataType="vm:HomePageViewModel">
<ContentPage.ToolbarItems>
<ToolbarItem
x:Name="ImportToolBar"
Text="Import"
Clicked="ImportToolBar_Clicked">
</ToolbarItem>
</ContentPage.ToolbarItems>
<Grid ColumnDefinitions="370,*">
<Grid Grid.Column="0"
Grid.Row="0"
RowDefinitions="300,*">
<Grid Grid.Row="0"
Grid.Column="0"
ColumnDefinitions="*"
RowDefinitions="*">
<Grid Grid.Row="0"
Grid.Column="0"
Margin="20, 45, 20, 20"
ColumnDefinitions="*,3*"
RowDefinitions="*,*,*,*,*,*,*">
<Label Grid.Row="0" Grid.Column="0" Text="Patient:" VerticalTextAlignment="Center"></Label>
<Entry
Grid.Row="0" Grid.Column="1" IsReadOnly="False" VerticalTextAlignment="Center"
HeightRequest="30" MinimumHeightRequest="30" Text="{Binding MyPatient}">
</Entry>
<Label Grid.Row="1" Grid.Column="0" Text="ID:" VerticalTextAlignment="Center"></Label>
<Entry
Grid.Row="1" Grid.Column="1" IsReadOnly="False" VerticalTextAlignment="Center"
HeightRequest="30" MinimumHeightRequest="30" Text="{Binding MyPatient.Id}"></Entry>
</Grid>
</Grid>
</Grid>
</Grid>
</ContentPage>
我的 HomePage.xaml.cs:
using Aequus.CoreBusiness;
using Aequus.Maui.ViewModels;
using Aequus.Maui.Views.Controls;
using Aequus.UseCases.Interfaces;
using DicomObjects;
using DicomObjects.Enums;
namespace Aequus.Maui.Views;
public partial class HomePage : ContentPage
{
private readonly HomePageViewModel homePageViewModel;
public HomePage(HomePageViewModel homePageViewModel)
{
InitializeComponent();
this.homePageViewModel = homePageViewModel;
this.BindingContext = this.homePageViewModel;
}
private async void ImportToolBar_Clicked(object sender, EventArgs e)
{
await Shell.Current.GoToAsync(nameof(ImportPage));
}
}
我的 HomePageViewModel - 在这里我使用一个 ApplyQueryAttributes 方法来获取在子页面 (ImportPage) 中选择的Dicom图像:
using Aequus.CoreBusiness;
using Aequus.UseCases.Interfaces;
using CommunityToolkit.Mvvm.ComponentModel;
using DicomObjects;
using DicomObjects.Enums;
namespace Aequus.Maui.ViewModels
{
public class HomePageViewModel : ObservableObject, IQueryAttributable
{
public Patient? MyPatient { get; set; }
public ILoadPatientUseCase LoadPatientUseCase { get; }
private DicomImage? currentDicomImage = null;
public HomePageViewModel(ILoadPatientUseCase loadPatientUseCase)
{
LoadPatientUseCase = loadPatientUseCase;
LoadPatientAsync();
}
public async Task LoadPatientAsync()
{
MyPatient = await LoadPatientUseCase.ExecuteAsync();
}
public void ApplyQueryAttributes(IDictionary<string, object> query)
{
if (query.TryGetValue("ReturnedObject", out var obj))
{
MyPatient.Lastname = "Peters";
MyPatient.Id = 2;
Application.Current.MainPage.DisplayAlert("MESSAGE", MyPatient.Lastname, "OK");
}
}
}
}
该 ImportPage.xaml:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Aequus.Maui.Views.ImportPage">
<Grid
RowDefinitions="50">
<Grid
Grid.Row="0"
ColumnDefinitions="*,*,*">
<Button
x:Name="btnImport"
Margin="10,0,10,0"
Grid.Column="1"
Text="Import"
Clicked="btnImport_Clicked">
</Button>
<Button
x:Name="btnCancel"
Margin="10,0,10,0"
Grid.Column="2"
Text="Cancel"
Clicked="btnCancel_Clicked">
</Button>
</Grid>
</Grid>
</ContentPage>
该 ImportPage.xaml.cs:
namespace Aequus.Maui.Views;
using DicomObjects;
public partial class ImportPage : ContentPage
{
public DicomImage? currentDicomImage;
public ImportPage()
{
InitializeComponent();
}
private async void btnImport_Clicked(object sender, EventArgs e)
{
}
private async void btnCancel_Clicked(object sender, EventArgs e)
{
//Shell.Current.GoToAsync("..");
await Shell.Current.GoToAsync($"//{nameof(HomePage)}");
// IN CHILD PAGE
var navigationParameter = new Dictionary<string, object>
{
{ "ReturnedObject", currentDicomImage }
};
await Shell.Current.GoToAsync("..", navigationParameter);
}
}
该 Patient 类:
namespace Aequus.CoreBusiness
{
// All the code in this file is included in all platforms.
public class Patient
{
public int Id { get; set; }
public string Lastname { get; set; }
public string Firstname { get; set; }
public override string ToString()
{
return Lastname + ", " + Firstname;
}
}
}
解决方案
这是因为你的属性在变化时没有通知UI,原因是你的模型没有对变化进行监听,
如果你使用的是CommunityToolkit.Maui.Mvvm,你需要将你的模型改成ObservableObject
public partial class Patient : ObservableObject
{
[ObservableProperty]
public int id;
public string Lastname { get; set; }
public string Firstname { get; set; }
public override string ToString()
{
return Lastname + ", " + Firstname;
}
}
对于任何需要绑定为双向属性的属性,也要类似处理。
另外我还注意到你的其中一个输入框绑定到了一个Patient对象?那样不会工作。文本是字符串,只有绑定成字符串时才会起作用。
如果你有任何问题,告诉我!
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。