【问题标题】:Xamarin.forms navigate to different page in shell from button click on pageXamarin.forms 从按钮单击页面导航到 shell 中的不同页面
【发布时间】:2020-03-25 19:14:15
【问题描述】:

我试图弄清楚如何通过单个页面上的按钮单击事件来浏览我的 shell 页面。我希望按钮单击与打开菜单并选择下一页一样。例如,我将有一系列页面,我从用户那里收集信息以构建报告。我希望用户在第一页输入一些数据,然后单击下一步进入第二页以输入更多信息,依此类推。我想要保留 shell 页面菜单的原因是,如果用户决定他们需要返回页面来修改以前输入的某些信息,他们可以打开 shell 菜单并选择页面,而不是单击返回按钮 n次返回上一页。

我尝试使用路由和 Shell.Current.GoToAsync() 来实现这一点,但得到一个空引用 在 UIApplication.Main(args, null, "AppDelegate"); 行的 Main.cs 中,我避免使用 Navigation.PushModalAsync(new Page2());,因为以这种方式导航会将汉堡菜单删除到我的 shell 页面。我还尝试在 ShellPage.xaml.cs 中创建一个名为 Change_Page() 的函数,我通过单击第一页的按钮调用该函数。在这个函数中,我尝试了相同的Shell.Current.GoToAsync("myPage2"),这再次导致了空引用错误,并尝试了Shell.Current.CurrentItem = myPage2;,这导致了同一行的中断,但是我得到了一些 UIKit.UIApllication 错误t 似乎显示错误,但确实在此处停止了调试器。

ShellPage.xaml

...
<FlyoutItem Title="Page1">
    <ShellContent>
        <views:Page1View Title="Page1" x:Name="myPage1" Route="myPage1"/>
    </ShellContent>
</FlyoutItem>
<FlyoutItem Title="Page2">
    <ShellContent>
        <views:Page2View Title="Page2" x:Name="myPage2" Route="myPage2"/>
    </ShellContent>
</FlyoutItem>
<FlyoutItem Title="Page3">
    <ShellContent>
        <views:Page1View Title="Page1" x:Name="myPage3" Route="myPage3"/>
    </ShellContent>
</FlyoutItem>
...

myShellPage.xaml.cs

[DesignTimeVisible(false)]
    public partial class MyShellPage : Shell
    {
        public MyShellPage()
        {
            InitializeComponent();

            Routing.RegisterRoute("myPage1", typeof(CallInfoPage));
            Routing.RegisterRoute("myPage2", typeof(SpillInfoPage));
            Routing.RegisterRoute("myPage3", typeof(ItemsPage));

            Device.StartTimer(TimeSpan.FromSeconds(3), () =>
            {
                // Do something
                Current.CurrentItem = myPage3; // throws error 'myPage3' does not exist in current context
                return false; // True = Repeat again, False = Stop the timer
            });
        }
    }

Page1View.xaml

...
<Button Text="Next" Clicked="Next_Clicked" />
...

Page1View.xaml.cs

...
async void Next_Clicked(System.Object sender, System.EventArgs e)
    {
        await Shell.Current.GoToAsync("myPage2");
    }
...

【问题讨论】:

    标签: c# xaml xamarin.forms xamarin.ios navigation


    【解决方案1】:

    运行时还需要Register page routes

    在 Shell 子类构造函数中,或在调用路由之前运行的任何其他位置中,可以为未在 Shell 可视层次结构中表示的任何页面显式注册其他路由:

    Routing.RegisterRoute("pageone", typeof(ItemsPage));
    Routing.RegisterRoute("pagetwo", typeof(AboutPage));
    

    然后可以使用基于 URI 的导航从应用程序中的任何位置导航到这些页面。此类页面的路由称为全局路由。

    async void NavigateThird_Clicked(object sender, EventArgs e)
    {
        await Shell.Current.GoToAsync("pagetwo");
    }
    

    有效。

    关于AppShell不能在Constructor方法中调用Shell.Current.GoToAsync("myPage2")Shell.Current.CurrentItem = myPage2。另外,你想显示汉堡菜单,你会看到Current.GoToAsync 不能那样做。在这里你需要使用Current.CurrentItem 来实现它。我有一个解决方法,方法是使用Timer 调用它们延迟一段时间。

    public AppShell()
    {
        InitializeComponent();
    
        Routing.RegisterRoute("pageone", typeof(ItemsPage));
        Routing.RegisterRoute("pagetwo", typeof(AboutPage));
        Routing.RegisterRoute("pagethird", typeof(PageThird));
    
        Device.StartTimer(TimeSpan.FromSeconds(3), () =>
        {
            // Do something
            Current.CurrentItem = pagethird;
            return false; // True = Repeat again, False = Stop the timer
        });
    }
    

    Xaml 代码:

    <FlyoutItem Title="main"
                FlyoutDisplayOptions="AsMultipleItems">
        <ShellContent x:Name="pageone" Title="Page1" FlyoutIcon="icon.png" ContentTemplate="{DataTemplate local:ItemsPage}" Route="pageone" />
        <ShellContent x:Name="pagetwo" Title="Page2"
                        FlyoutIcon="icon.png"
                        ContentTemplate="{DataTemplate local:AboutPage}" Route="pagetwo" />
    </FlyoutItem>
    <FlyoutItem Title="Two" x:Name="pagethird">
        <ShellContent  Title="Page3"
                        FlyoutIcon="icon.png"
                        ContentTemplate="{DataTemplate local:PageThird}"
                        Route="pagethird" />
    </FlyoutItem>
    

    效果:

    【讨论】:

    • 感谢您的回复。当您单击TOSECONDPAGE 按钮时,我想要实现的是在第二页上保留汉堡菜单以访问我的外壳。所以看看你的 gif,这和我从汉堡菜单打开 shell 并单击 page2 一样。而不是在单击按钮后在第二页上有后退按钮。这可能吗?
    • @tbartlett17 是的,你会看到汉堡菜单会隐藏。使用Shell.Current.GoToAsync("pagetwo") 不会避免这种情况,您需要使用Current.CurrentItem = pagethird; 才能实现您想要的。我会更新答案。
    • 你能解释一下你的定时器在做什么吗?我在计时器块中的Current.CurrentItem = pagethird; 行也遇到了错误。错误是 pagethird 在此上下文中不存在。
    • @tbartlett17 计时器用于避免在Constructor 方法中直接不工作,这只是使Current.CurrentItem 工作的一种解决方法。您需要检查是否在 xaml 中声明了pagethird,我将更新 xaml 代码。
    • @tbartlett17 x:Name="pagethird" 应该在 xaml 中声明,然后它将起作用。
    猜你喜欢
    • 2021-08-19
    • 1970-01-01
    • 2021-06-15
    • 1970-01-01
    • 1970-01-01
    • 2022-01-04
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    相关资源
    最近更新 更多