XAML MAUI MVVM导航,如何从页面导航回MainPage

kiz8lqtg  于 2023-09-28  发布在  其他
关注(0)|答案(2)|浏览(207)

我正在学习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));
        }

类型或命名空间MainPageProjectName.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
好的.
你能告诉我下一个陈述是否正确吗?下面是我对AddSingletonAddTransient之间区别的解释:
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。我敢打赌,如果我读这些文件,而不是略读,我会找到我的答案。

jchrr9hc

jchrr9hc1#

好吧
ProjectName.View中不存在类型或命名空间MainPage(是否缺少程序集引用?)
首先,我建议你把你的页面命名为HomePage。MainPage是非常具体的东西,我看你是新来的,你只会把自己搞糊涂。
第二,在MainPage.xaml.cs中。第一行类似于:

namespece ProjectName.View;

您不必移动文件。这条线是当你移动它时会发生变化的,这就是为什么你有时能让它工作,有时不能。
如果这一行有.View,就用View.MainPage。如果你不这样做,你就只使用MainPage
第二:

builder.Services.AddSingleton<MainPage>();

应将其更改为 transient 。

builder.Services.AddTransient<MainPage>();

shell 要求。(不好的事情会发生)。
第三:
不要这样设置路由:

Routing.RegisterRoute(nameof(View.MainPage), typeof(View.MainPage));

同时在XAML中使用路由:

Route="MainPage"

关于导航:在这里阅读,开始到结束:https://learn.microsoft.com/en-us/dotnet/maui/fundamentals/shell/navigation
澄清一下。
假设MainPage是我的主页,我将SecondPage定义为全局路由,我想从任何地方调用它。
这意味着MainPage保留在XAML中。

<ShellContent
        Title="Main Page"
        ContentTemplate="{DataTemplate local:MainPage}"
        Route="MainPage" />

SecondPage仍然在CS中:

Routing.RegisterRoute(nameof(View.SecondPage), typeof(View.SecondPage));

当应用程序启动时,它将在XAML(即您的主页)中查找最顶部的ShellItem,并将您导航到那里。
导航堆栈看起来像这样//MainPage。
然后你可以调用GoToAsync("SecondPage")。您将被导航到SecondPage。导航堆栈看起来像这个//MainPage/SecondPage
要返回,您可以使用“..”导航(返回按钮的默认行为将执行此操作)。
这里常见的错误是调用“//SecondPage”。为了能够将SecondPage保留为堆栈的唯一页面,它必须注册为ShellItem。(您需要以添加MainPage的方式添加它)。
从两页开始,不要试图一次写所有的东西,因为一次纠正所有错误几乎是不可能的。逐步构建您的项目。

mqkwyuun

mqkwyuun2#

1.根据您的帖子详细信息,您希望从SecondPage.xaml导航回MainPage.xaml,如下所示:

SecondPage --> FirstPage --> MainPage

您应该使用向后导航,可以通过指定“..”作为GoToAsync的参数来执行。
所以你需要像下面这样定义你的SecondPageViewModel.cs

public partial class SecondPageViewModel 
{
     [RelayCommand]
      async Task NavigateTopage()
      {
          await Shell.Current.GoToAsync("../../");
      }

}

1.您的项目结构应该如下所示,MainPage.xamlFirstPage.xamlSecondPage.xaml包含在View文件夹中。

查看:

  • FirstPage.xaml
  • MainPage.xaml
  • SecondPage.xaml

你应该像下面这样定义AppShell.cs

using EMS_MOBILE_MAUI.View; 

namespace EMS_MOBILE_MAUI;

public partial class AppShell : Shell
{
      public AppShell()
      {
          InitializeComponent();

        Routing.RegisterRoute(nameof(FirstPage), typeof(FirstPage));
        Routing.RegisterRoute(nameof(SecondPage), typeof(SecondPage));
    }
}

1.关于错误:Compiler Error CS0246下面,有许多原因可能导致此错误。请参见https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-messages/cs0246。这个错误与DI无关:AddSingletonAddTransient

相关问题