Xamarin 应用程序无法返回
Xamarin application not navigating back
问题
这是过程:
Select 来自列表的 category
。
加载Tasks page
.
Tasks
根据上一页选择的 categoryId
加载。 (可以导航回 Category page
✔️)
Select 来自列表的 Task
。
加载Task Page
.
页面上加载了任务详细信息。 (无法导航回“任务”页面 ❌)
视频
问题
我不明白为什么我无法返回页面。我该如何解决这个问题?
代码
CategoriesViewModel
public class CategoriesViewModel : BaseViewModel
{
public ObservableCollection<CategoryModel> Categories { get; } = new ObservableCollection<CategoryModel>();
public Command LoadCategoriesCommand { get; }
public Command<CategoryModel> SelectedCategory { get; }
public CategoriesViewModel()
{
Title = "Categories";
LoadCategoriesCommand = new Command(async () => await LoadCategories());
SelectedCategory = new Command<CategoryModel>(OnSelectedCategory);
}
private async Task LoadCategories()
{
IsBusy = true;
try
{
Categories.Clear();
var categories = await DatabaseService.GetCategoriesAsync();
foreach (var category in categories)
{
this.Categories.Add(category);
}
}
catch (Exception)
{
throw;
}
finally
{
IsBusy = false;
}
}
private async void OnSelectedCategory(CategoryModel category)
{
if (category == null)
return;
await Shell.Current.GoToAsync($"{nameof(TasksPage)}?{nameof(TasksViewModel.CategoryId)}={category.CategoryId}");
}
public void OnAppearing()
{
IsBusy = true;
}
}
TasksViewModel
[QueryProperty(nameof(CategoryId), nameof(CategoryId))]
public class TasksViewModel : BaseViewModel
{
public ObservableCollection<TaskModel> Tasks { get; } = new ObservableCollection<TaskModel>();
private int categoryId;
public int CategoryId
{
get { return categoryId; }
set
{
categoryId = value;
}
}
public Command LoadTasksCommand { get; set; }
public Command<TaskModel> SelectedTask { get; set; }
public TasksViewModel()
{
Title = "Tasks";
LoadTasksCommand = new Command(async () => await LoadTasks());
SelectedTask = new Command<TaskModel>(OnSelectedTask);
}
private async Task LoadTasks()
{
IsBusy = true;
try
{
this.Tasks.Clear();
var tasks = await DatabaseService.GetTasksAsync(CategoryId);
foreach (var task in tasks)
{
this.Tasks.Add(task);
}
}
catch (Exception)
{
throw;
}
finally
{
IsBusy = false;
}
}
private async void OnSelectedTask(TaskModel task)
{
if (task == null)
return;
await Shell.Current.GoToAsync($"{nameof(TaskPage)}?{nameof(TaskViewModel.TaskId)}={task.TaskId}");
}
public void OnAppearing()
{
IsBusy = true;
}
}
TaskViewModel
[QueryProperty(nameof(TaskId), nameof(TaskId))]
public class TaskViewModel : BaseViewModel
{
private int taskId;
public int TaskId
{
get { return taskId; }
set
{
taskId = value;
}
}
private string taskTitle;
public string TaskTitle
{
get { return taskTitle; }
set
{
taskTitle = value;
OnPropertyChanged(nameof(TaskTitle));
}
}
private string description;
public string Description
{
get { return description; }
set
{
description = value;
OnPropertyChanged(nameof(Description));
}
}
public Command LoadTaskCommand { get; }
public TaskViewModel()
{
LoadTaskCommand = new Command(async () => await LoadTask());
}
private async Task LoadTask()
{
IsBusy = true;
try
{
var task = await DatabaseService.GetTaskAsync(TaskId);
this.TaskTitle = task.Title;
this.Description = task.Description;
}
catch (Exception)
{
throw;
}
finally
{
IsBusy = false;
}
}
public void OnAppearing()
{
IsBusy = true;
}
}
更新 1
我尝试替换 TasksViewModel
中的这行代码:
await Shell.Current.GoToAsync($"{nameof(TaskPage)}?{nameof(TaskViewModel.TaskId)}={task.TaskId}");
对此:
await Shell.Current.Navigation.PushAsync(new AboutPage());
同样的结果。
更新 2
根据请求的评论,这里是 TaskPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:vm="clr-namespace:SomeProject.ViewModels"
x:Class="SomeProject.Views.Task.TaskPage"
Title="{Binding TaskTitle}">
<ContentPage.Content>
<RefreshView x:DataType="vm:TaskViewModel"
Command="{Binding LoadTaskCommand}"
IsRefreshing="{Binding IsBusy, Mode=TwoWay}">
<StackLayout>
<Label Text="{Binding Description}" />
</StackLayout>
</RefreshView>
</ContentPage.Content>
</ContentPage>
和TaskPage.xaml.cs
:
public partial class TaskPage : ContentPage
{
TaskViewModel _viewModel;
public TaskPage()
{
InitializeComponent();
BindingContext = _viewModel = new TaskViewModel();
}
protected override void OnAppearing()
{
base.OnAppearing();
_viewModel.OnAppearing();
}
}
更新 3
根据请求的评论,这里是 routes
:
public AppShell()
{
InitializeComponent();
Routing.RegisterRoute(nameof(CategoriesView), typeof(CategoriesView));
Routing.RegisterRoute(nameof(TasksPage), typeof(TasksPage));
Routing.RegisterRoute(nameof(TaskPage), typeof(TaskPage));
}
检查您的收银机路线。
In the Shell subclass constructor, or any other location that runs
before a route is invoked, additional routes can be explicitly
registered for any pages that aren't represented in the Shell visual
hierarchy
我已经 CategoryPage
在 AppShell.xaml.cs
注册了 AppShell.xaml
也是这样:
<ShellContent Route="CategoryPage" ContentTemplate="{DataTemplate local:CategoryPage}" />
只能在一个或另一个中注册一个路由。
问题
这是过程:
Select 来自列表的
category
。加载
Tasks page
.Tasks
根据上一页选择的categoryId
加载。 (可以导航回Category page
✔️)Select 来自列表的
Task
。加载
Task Page
.页面上加载了任务详细信息。 (无法导航回“任务”页面 ❌)
视频
问题
我不明白为什么我无法返回页面。我该如何解决这个问题?
代码
CategoriesViewModel
public class CategoriesViewModel : BaseViewModel
{
public ObservableCollection<CategoryModel> Categories { get; } = new ObservableCollection<CategoryModel>();
public Command LoadCategoriesCommand { get; }
public Command<CategoryModel> SelectedCategory { get; }
public CategoriesViewModel()
{
Title = "Categories";
LoadCategoriesCommand = new Command(async () => await LoadCategories());
SelectedCategory = new Command<CategoryModel>(OnSelectedCategory);
}
private async Task LoadCategories()
{
IsBusy = true;
try
{
Categories.Clear();
var categories = await DatabaseService.GetCategoriesAsync();
foreach (var category in categories)
{
this.Categories.Add(category);
}
}
catch (Exception)
{
throw;
}
finally
{
IsBusy = false;
}
}
private async void OnSelectedCategory(CategoryModel category)
{
if (category == null)
return;
await Shell.Current.GoToAsync($"{nameof(TasksPage)}?{nameof(TasksViewModel.CategoryId)}={category.CategoryId}");
}
public void OnAppearing()
{
IsBusy = true;
}
}
TasksViewModel
[QueryProperty(nameof(CategoryId), nameof(CategoryId))]
public class TasksViewModel : BaseViewModel
{
public ObservableCollection<TaskModel> Tasks { get; } = new ObservableCollection<TaskModel>();
private int categoryId;
public int CategoryId
{
get { return categoryId; }
set
{
categoryId = value;
}
}
public Command LoadTasksCommand { get; set; }
public Command<TaskModel> SelectedTask { get; set; }
public TasksViewModel()
{
Title = "Tasks";
LoadTasksCommand = new Command(async () => await LoadTasks());
SelectedTask = new Command<TaskModel>(OnSelectedTask);
}
private async Task LoadTasks()
{
IsBusy = true;
try
{
this.Tasks.Clear();
var tasks = await DatabaseService.GetTasksAsync(CategoryId);
foreach (var task in tasks)
{
this.Tasks.Add(task);
}
}
catch (Exception)
{
throw;
}
finally
{
IsBusy = false;
}
}
private async void OnSelectedTask(TaskModel task)
{
if (task == null)
return;
await Shell.Current.GoToAsync($"{nameof(TaskPage)}?{nameof(TaskViewModel.TaskId)}={task.TaskId}");
}
public void OnAppearing()
{
IsBusy = true;
}
}
TaskViewModel
[QueryProperty(nameof(TaskId), nameof(TaskId))]
public class TaskViewModel : BaseViewModel
{
private int taskId;
public int TaskId
{
get { return taskId; }
set
{
taskId = value;
}
}
private string taskTitle;
public string TaskTitle
{
get { return taskTitle; }
set
{
taskTitle = value;
OnPropertyChanged(nameof(TaskTitle));
}
}
private string description;
public string Description
{
get { return description; }
set
{
description = value;
OnPropertyChanged(nameof(Description));
}
}
public Command LoadTaskCommand { get; }
public TaskViewModel()
{
LoadTaskCommand = new Command(async () => await LoadTask());
}
private async Task LoadTask()
{
IsBusy = true;
try
{
var task = await DatabaseService.GetTaskAsync(TaskId);
this.TaskTitle = task.Title;
this.Description = task.Description;
}
catch (Exception)
{
throw;
}
finally
{
IsBusy = false;
}
}
public void OnAppearing()
{
IsBusy = true;
}
}
更新 1
我尝试替换 TasksViewModel
中的这行代码:
await Shell.Current.GoToAsync($"{nameof(TaskPage)}?{nameof(TaskViewModel.TaskId)}={task.TaskId}");
对此:
await Shell.Current.Navigation.PushAsync(new AboutPage());
同样的结果。
更新 2
根据请求的评论,这里是 TaskPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:vm="clr-namespace:SomeProject.ViewModels"
x:Class="SomeProject.Views.Task.TaskPage"
Title="{Binding TaskTitle}">
<ContentPage.Content>
<RefreshView x:DataType="vm:TaskViewModel"
Command="{Binding LoadTaskCommand}"
IsRefreshing="{Binding IsBusy, Mode=TwoWay}">
<StackLayout>
<Label Text="{Binding Description}" />
</StackLayout>
</RefreshView>
</ContentPage.Content>
</ContentPage>
和TaskPage.xaml.cs
:
public partial class TaskPage : ContentPage
{
TaskViewModel _viewModel;
public TaskPage()
{
InitializeComponent();
BindingContext = _viewModel = new TaskViewModel();
}
protected override void OnAppearing()
{
base.OnAppearing();
_viewModel.OnAppearing();
}
}
更新 3
根据请求的评论,这里是 routes
:
public AppShell()
{
InitializeComponent();
Routing.RegisterRoute(nameof(CategoriesView), typeof(CategoriesView));
Routing.RegisterRoute(nameof(TasksPage), typeof(TasksPage));
Routing.RegisterRoute(nameof(TaskPage), typeof(TaskPage));
}
检查您的收银机路线。
In the Shell subclass constructor, or any other location that runs before a route is invoked, additional routes can be explicitly registered for any pages that aren't represented in the Shell visual hierarchy
我已经 CategoryPage
在 AppShell.xaml.cs
注册了 AppShell.xaml
也是这样:
<ShellContent Route="CategoryPage" ContentTemplate="{DataTemplate local:CategoryPage}" />
只能在一个或另一个中注册一个路由。