我有一个 .NET MAUI 应用程序,它使用数据库和 shell 选项卡栏进行页面导航。
其中一个页面“客户端”显示来自数据库的数据,并在每次显示页面时加载。
我遇到了一个问题,当我在 TabBar 上的页面上移动时,每次访问“客户端”页面时,从数据库检索到的数据都会堆积在以前的结果上。
我能够通过添加我在here找到的代码来解决这个问题:
public partial class AppShell : Shell
{
public AppShell()
{
InitializeComponent();
}
ShellContent _previousShellContent;
protected override void OnNavigated(ShellNavigatedEventArgs args)
{
base.OnNavigated(args);
if (CurrentItem?.CurrentItem?.CurrentItem is not null &&
_previousShellContent is not null)
{
var property = typeof(ShellContent)
.GetProperty("ContentCache", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy);
property.SetValue(_previousShellContent, null);
}
_previousShellContent = CurrentItem?.CurrentItem?.CurrentItem;
}
}
然后,我添加了一个子页面“NewClientPage”,该子页面从“客户”页面分支出来并使用
进行导航ClientsPage.xaml.cs
:
private async void AddClient_Clicked(object sender, EventArgs e){
await Shell.Current.GoToAsync("NewClientPage");
}
App.xaml.cs
:
Routing.RegisterRoute("NewClientPage", typeof(NewClientPage));
并使用
GoToAsync()
返回“客户端”页面(未使用内置返回按钮,因为它没有按我的预期工作)。
现在,转到
NewClientPage
,返回 ClientsPage
,然后转到 TabBar 上的其他页面后,也存在重复使用先前页面内容的问题。
例如,
其中
MainPage
和 ClientsPage
位于 TabBar 上。
4点从NewClientPage回来后,ClientsPage看起来不错。但是,如果我转到其他页面并返回,新加载的数据将显示在上一页内容下,并显示为重复项。
这是加载页面的代码。参考了这个视频。
ClientsViewModel.cs
:
public partial class ClientsViewModel : ObservableObject
{
private readonly DatabaseContext _context;
public ClientsViewModel(DatabaseContext context)
{
_context = context;
}
public async Task LoadClientsAsync()
{
var clients = await _context.GetAllAsync<Client>();
if (clients is not null && clients.Any())//if we have at least one client
{
Clients ??= new ObservableCollection<Client>(); //if null, initialize
foreach (var client in clients)//insert each client into a obervable collection Clients
{
Clients.Add(client);
}
}
}
}
这在 OnAppearing() 中调用。
ClientsPage.xaml
:
public partial class ClientsPage : ContentPage
{
private readonly ClientsViewModel _viewModel;
public ClientsPage(ClientsViewModel viewModel)
{
InitializeComponent();
BindingContext = viewModel;
_viewModel = viewModel;
}
protected async override void OnAppearing()
{
base.OnAppearing();
await _viewModel.LoadClientAsync();
}
}
当我调试时,
OnNavigated
似乎正在运行,但使用GoToAsync后仍然残留着之前的数据。
当我在 NewClientPage
上时,CurrentItem?.CurrentItem?.CurrentItem.Title
是客户端。我猜当 _previousShellContent == CurrentItem?.CurrentItem?.CurrentItem
像 Clients(on ClientsPage) == Clients(actually on NewClientPage)
时有问题,但我不确定。我正在 Android 上测试。
我该如何解决这个问题?
代码片段重现该错误。
您可以尝试先清除数据再重新加载数据,代码如下:
Clients.Clear();
请参考以下代码:
public partial class ClientsViewModel : ObservableObject
{
public async Task LoadClientsAsync()
{
await ExecuteAsync(async () =>
{
var clients = await _context.GetAllAsync<Client>();
Console.WriteLine("length = " + clients.LongCount());
if (clients is not null && clients.Any())//if we have at least one client
{
Clients ??= new ObservableCollection<Client>(); //if null, initialize
//clear data before adding data again.
Clients.Clear();
foreach (var client in clients)//insert each client into a obervable collection Clients
{
Clients.Add(client);
}
}
}, "Fetching clients...");
}
}