我正在学习Maui MVVM的工作原理。我想写这样的代码:
- 从
MainPage.xaml
开始,这里有一个按钮可以让你: FirstPage.xaml
,其中有一个按钮,可以将您带到:SecondPage.xaml
,这里有一个按钮可以让你回到:MainPage.xaml
,这里还有一个按钮,可以让你:FirstPage.xaml
等等
问题是我不能从SecondPage.xaml
回到MainPage.xaml
。
问题出在哪里?
我需要从SecondPage
导航回MainPage
的代码行,但它给出了一个错误:
public AppShell()
{
InitializeComponent();
this line>> Routing.RegisterRoute(nameof(View.MainPage), typeof(View.MainPage));
Routing.RegisterRoute(nameof(View.FirstPage), typeof(View.FirstPage));
Routing.RegisterRoute(nameof(View.SecondPage), typeof(View.SecondPage));
}
类型或命名空间MainPage
在ProjectName.View中不存在(是否缺少程序集引用?)
唉,我没有错过一个汇编引用。
值得注意的是,我将MainPage.xaml
移到了一个 View 文件夹中,但是当我将它移回root目录时,仍然会收到这条消息。
这是有道理的,我不能把路由信息的起始页,因为有排序的已经 * 是 * 路由代码为它在AppShell.xaml
:
<ShellContent
Title="Main Page"
ContentTemplate="{DataTemplate local:MainPage}"
Route="MainPage" />
那么,如何返回到MainPage.xaml
呢?
下面是我的代码供参考
使用CommunityToolkit.MVVM
Nuget包。
在MauiProgram.cs
中添加依赖注入:
builder.Services.AddSingleton<MainPage>();
builder.Services.AddSingleton<MainPageViewModel>();
builder.Services.AddSingleton<FirstPage>();
builder.Services.AddSingleton<FirstPageViewModel>();
builder.Services.AddSingleton<SecondPage>();
builder.Services.AddSingleton<SecondPageViewModel>();
在App.Shell.xaml.cs
中添加路由信息:
public AppShell()
{
InitializeComponent();
Routing.RegisterRoute(nameof(View.FirstPage), typeof(View.FirstPage));
Routing.RegisterRoute(nameof(View.SecondPage), typeof(View.SecondPage));
}
对于每个页面,执行以下操作:
为每个Page创建一个ViewModel类。
从页面的代码后面将绑定上下文添加到ViewModels:
public partial class FirstPage : ContentPage
{
public FirstPage(FirstPageViewModel firstPageViewModel)
{
InitializeComponent();
BindingContext = firstPageViewModel;
}
}
在Page.xaml
中,确保文件可以访问并与其对应的ViewModel对话,并添加一个具有命令的按钮(或其他东西)(* 注意此代码对每个Page都是通用的 *):
<ContentPage ...
xmlns:viewmodel="clr-namespace:ProjectName.ViewModel"
x:DataType="viewmodel:PageViewModel">
<Button ...
Command="{Binding NavigateToPageCommand}"/>
</ContentPage>
最后,确保PageViewModel.cs
中的Command有对应的方法,如下所示:
public partial class PageViewModel
{
[RelayCommand]
async Task NavigateToPage()
{
await Shell.Current.GoToAsync(nameof(View.Page));
}
}
EDIT:回复已接受的建议
(1)将您的主页命名为HomePage
。不要混淆自己。
好的.
(2)* 在MainPage.xaml.cs中。第一行类似于**namespace ProjectName.View;
去掉View
。**
我没有那种感觉。下面是我的文件MainPage.xaml.cs
:
namespace EMS_MOBILE_MAUI
{
public partial class MainPage : ContentPage
{
public MainPage(MainPageViewModel mainPageViewModel)
{
InitializeComponent();
BindingContext = mainPageViewModel;
}
}
}
(3)将MainPage
的DI从AddSingleton
更改为AddTransient
。
好的.
你能告诉我下一个陈述是否正确吗?下面是我对AddSingleton
和AddTransient
之间区别的解释:AddSingleton
的意思是:静态的一次性页面。一方面,你可以改变页面的状态,离开它,回来,它仍然会在那个状态。
另一方面,如果你浏览到另一个页面并再次返回,AddTransient
将导致页面重新“更新”。
(3)你不应该有这两行代码:
- MauiProgram.cs*:
Routing.RegisterRoute(nameof(View.MainPage), typeof(View.MainPage));
- AppShell.xaml.xs:*
<ShellContent
Title="LoginPage"
ContentTemplate="{DataTemplate local:MainPage}"
Route="MainPage" />
我没有这两条线。我只有第二行。
由于MainPage
的路由已经在AppShell.xaml.cs
中,所以我不使用其他路由行。我把这句话放在问题的开头,作为我认为问题可能存在的证明。
(4)阅读文档。小心。例如,我打赌你不知道你可以用“.."返回。
对你说的对我并不是在考虑你推/弹出的堆栈方面的导航。我会的
总之,我能对代码做的唯一实际更改是将MainPage
的DI从AddSingleton
更改为AddTransient
,这不会改变行为,因为我仍然无法从任何Page导航回MainPage
。我敢打赌,如果我读这些文件,而不是略读,我会找到我的答案。
2条答案
按热度按时间jchrr9hc1#
好吧
ProjectName.View中不存在类型或命名空间MainPage(是否缺少程序集引用?)
首先,我建议你把你的页面命名为HomePage。MainPage是非常具体的东西,我看你是新来的,你只会把自己搞糊涂。
第二,在MainPage.xaml.cs中。第一行类似于:
您不必移动文件。这条线是当你移动它时会发生变化的,这就是为什么你有时能让它工作,有时不能。
如果这一行有
.View
,就用View.MainPage
。如果你不这样做,你就只使用MainPage
。第二:
应将其更改为 transient 。
shell 要求。(不好的事情会发生)。
第三:
不要这样设置路由:
同时在XAML中使用路由:
关于导航:在这里阅读,开始到结束:https://learn.microsoft.com/en-us/dotnet/maui/fundamentals/shell/navigation
澄清一下。
假设MainPage是我的主页,我将SecondPage定义为全局路由,我想从任何地方调用它。
这意味着MainPage保留在XAML中。
SecondPage仍然在CS中:
当应用程序启动时,它将在XAML(即您的主页)中查找最顶部的ShellItem,并将您导航到那里。
导航堆栈看起来像这样//MainPage。
然后你可以调用
GoToAsync("SecondPage")
。您将被导航到SecondPage。导航堆栈看起来像这个//MainPage/SecondPage
。要返回,您可以使用“..”导航(返回按钮的默认行为将执行此操作)。
这里常见的错误是调用“//SecondPage”。为了能够将SecondPage保留为堆栈的唯一页面,它必须注册为ShellItem。(您需要以添加MainPage的方式添加它)。
从两页开始,不要试图一次写所有的东西,因为一次纠正所有错误几乎是不可能的。逐步构建您的项目。
mqkwyuun2#
1.根据您的帖子详细信息,您希望从
SecondPage.xaml
导航回MainPage.xaml
,如下所示:您应该使用向后导航,可以通过指定“..”作为
GoToAsync
的参数来执行。所以你需要像下面这样定义你的
SecondPageViewModel.cs
:1.您的项目结构应该如下所示,
MainPage.xaml
,FirstPage.xaml
和SecondPage.xaml
包含在View文件夹中。查看:
你应该像下面这样定义
AppShell.cs
:1.关于错误:Compiler Error CS0246下面,有许多原因可能导致此错误。请参见https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-messages/cs0246。这个错误与DI无关:
AddSingleton
和AddTransient
。