【问题标题】:How to create a MasterDetailPage using MvvmCross?如何使用 MvvmCross 创建 MasterDetailPage?
【发布时间】:2018-08-05 10:28:01
【问题描述】:

我正在尝试使用 MvvmCross 开发 Xamarin.Forms 应用程序,我想使用 Hamburguer 菜单 (MasterDetailPage),但我不知道该怎么做。我尝试了不同的方法,搜索了教程和示例,但没有成功。谁能帮我?

【问题讨论】:

    标签: xamarin xamarin.forms mvvmcross


    【解决方案1】:

    正如您在此处看到的MvvmCross Playground,您应该首先创建一个 RootViewModel、MenuViewModel 和 FirstViewModel。然后在您的 UI 文件夹中创建一个 RootPage、MenuPage 和 FirstPage。

    您的 RootViewModel 应如下所示:

    public class RootViewModel : BaseViewModel
    {
        private readonly IMvxNavigationService _navigationService;
        public RootViewModel(IMvxNavigationService navigationService)
        {
            _navigationService = navigationService;
        }
    
        public override void ViewAppearing()
        {
            base.ViewAppearing();
    
            MvxNotifyTask.Create(async ()=> await this.InitializeViewModels();
        }
    
        private async Task InitializeViewModels()
        {
            await _navigationService.Navigate<MenuViewModel>();
            await _navigationService.Navigate<FirstViewModel>();
        }
    }
    

    编辑:我将导航移至异步任务以避免使用 async void。

    xaml RootPage 必须实现 MvxMasterDetailPage:

    <?xml version="1.0" encoding="UTF-8"?>
    <views:MvxMasterDetailPage x:TypeArguments="viewModels:RootViewModel"
        xmlns="http://xamarin.com/schemas/2014/forms"
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
        xmlns:views="clr-namespace:MvvmCross.Forms.Views;assembly=MvvmCross.Forms"
        xmlns:mvx="clr-namespace:MvvmCross.Forms.Bindings;assembly=MvvmCross.Forms"
        xmlns:viewModels="clr-namespace:yournamespace.Core.ViewModels"
        x:Class="yournamespace.UI.Views.RootPage"
        Icon="hamburger.png">
    </views:MvxMasterDetailPage>
    

    和后面的c#代码像这样使用presenter:

    [MvxMasterDetailPagePresentation(MasterDetailPosition.Root, WrapInNavigationPage = false)]
    public partial class RootPage : MvxMasterDetailPage<RootViewModel>
    {
        public RootPage()
        {
            InitializeComponent();
        }
    
        protected override void OnAppearing()
        {
            base.OnAppearing();
        }
    }
    

    MenuPage 必须是普通的 MvxContentPage 和 c# 代码在演示者的菜单页面上实现:

    [MvxMasterDetailPagePresentation(MasterDetailPosition.Master)]
    

    FirstPage 也是 MvxContentPage 并且所有的详细页面必须是:

    [MvxMasterDetailPagePresentation(MasterDetailPosition.Detail, NoHistory = true)]
    

    在所有页面中添加无历史记录以防止导航返回错误。

    编辑:我忘记了,导航后菜单没有关闭的错误,可能他们会在 MvvmCross 版本 6 上修复,现在要修复它,您必须将其粘贴到导航中执行导航前的任务:

    if(Application.Current.MainPage is MasterDetailPage masterDetailPage)
    {
        masterDetailPage.IsPresented = false; 
    }
    else if(Application.Current.MainPage is NavigationPage navigationPage && navigationPage.CurrentPage is MasterDetailPage nestedMasterDetail)
    {
        nestedMasterDetail.IsPresented = false;
    }
    

    【讨论】:

    • 感谢@fabribertani,这帮助很大。不允许汉堡菜单从左侧滑动怎么办?我想禁用此功能,因为我想构建自己的菜单系统,该系统始终通过 ContentViews 可见。
    • @RogerW 正如您在菜单中看到的那样,不要关闭修复我补充说您可以使用相同的方法,但将 IsPresented 属性设置为 true 并添加另一个名为 IsGestureEnabled 的属性并将其设置为 false。
    • 确保MenuPage 具有Title 属性集。否则你会得到可怕的Cannot replace MainPage root 错误并且你的应用程序会崩溃。如果我们知道这一点,它会为我们节省 2-3 天的错误查找时间。
    • 很好@NickTiberi,你能在 mvvmcross repo 中打开一个问题来报告 tihs 吗? github.com/MvvmCross/MvvmCross
    • @FabriBertani,使用此示例,我注意到在导航到 RootViewModel 时,FirstViewModel 构造函数被调用了 2 次。为什么会这样?
    猜你喜欢
    • 2019-03-11
    • 1970-01-01
    • 1970-01-01
    • 2015-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-20
    相关资源
    最近更新 更多