为MvxTabBarViewController调用ShowViewModel时的NullReference

时间:2016-08-10 18:41:00

标签: xamarin xamarin.ios mvvmcross

我创建了一个MvxTabBarViewController,当我尝试使用ShowViewModel方法打开时,会发生NullReferenceException。 ViewModel属性始终为null,如果我尝试instanciate,则会发生异常。

有我的MvxTabViewController

[Register("ProjectDetailsView")]
public class ProjectDetailsView : MvxTabBarViewController<ProjectDetailsViewModel>
{
    private JVMenuPopoverViewController _menuController;

    public override void ViewDidLoad()
    {
        base.ViewDidLoad();

        if (ViewModel == null)
        {
            ViewModel = new ProjectDetailsViewModel();
        }

        CriaAbas();
        CriaMenu();
    }

    private void CriaMenu()
    {
        var itensMenu = new List<JVMenuItem>();
        var selectFavoriteProjectsItem = new JVMenuActionItem
        {
            Title = "Select Favorite Projects",
            Command = () =>
            {
                var favoriteProjectsView = this.CreateViewControllerFor<FavoriteProjectsViewModel>() as UIViewController;
                NavigationController.PushViewController(favoriteProjectsView, true);
            }
        };

        itensMenu.Add(selectFavoriteProjectsItem);

        var logoutItem = new JVMenuActionItem()
        {
            Title = "Logout",
            Command = ViewModel.LogoutCommand.Execute
        };

        itensMenu.Add(logoutItem);

        _menuController = new JVMenuPopoverViewController(itensMenu);

        var menuButton = new UIBarButtonItem();
        menuButton.Clicked += (sender, args) =>
        {
            _menuController.ShowMenuFromController(this);
        };
        menuButton.Image = UIImage.FromBundle("images/ic_menu_white_36pt.png");

        NavigationItem.RightBarButtonItem = menuButton;
    }

    private void CriaAbas()
    {
        var abas = new List<UIViewController>();
        var controller = new UINavigationController();
        var informationView = this.CreateViewControllerFor(ViewModel.ProjectInformationViewModel) as UIViewController;
        informationView.TabBarItem = new UITabBarItem("Information", UIImage.FromBundle("images/ic_info_outline.png"), 0);
        informationView.Title = "Information";
        controller.PushViewController(informationView, false);

        abas.Add(informationView);

        controller = new UINavigationController();
        var milestonesView = this.CreateViewControllerFor(ViewModel.ProjectMilestonesViewModel) as UIViewController;
        milestonesView.TabBarItem = new UITabBarItem("Milestones", UIImage.FromBundle("images/ic_assistant_photo_48pt.png"), 0);
        milestonesView.Title = "Milestones";
        controller.PushViewController(milestonesView, false);

        abas.Add(milestonesView);

        ViewControllers = abas.ToArray();
        SelectedViewController = ViewControllers[0];
    }
}

我正在尝试打开此视图,调用ShowViewModel();

我做错了什么?

我的堆栈跟踪有一部分:

mvx: Diagnostic:  72,18 Showing ViewModel ProjectDetailsViewModel
iOSNavigation: Diagnostic:  72,18 Navigate requested
Unhandled Exception:

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.NullReferenceException: Object reference not set to an instance of an object
at MvvmCross.iOS.Views.MvxTabBarViewController.set_DataContext (System.Object value) [0x00001] in C:\vcs\git\MvvmCross\MvvmCross\iOS\iOS\Views\MvxTabBarViewController.cs:38 
at MvvmCross.iOS.Views.MvxTabBarViewController.set_ViewModel (IMvxViewModel value) [0x00001] in C:\vcs\git\MvvmCross\MvvmCross\iOS\iOS\Views\MvxTabBarViewController.cs:44 
at MvvmCross.iOS.Views.MvxTabBarViewController`1[TViewModel].set_ViewModel (MvvmCross.iOS.Views.TViewModel value) [0x00001] in C:\vcs\git\MvvmCross\MvvmCross\iOS\iOS\Views\MvxTabBarViewController.cs:68 
at PROSPERI_EPMFast.iOS.Views.ProjectDetailsView.ViewDidLoad () [0x00016] in C:\Projetos Vinicius\PROSPERI_EPMFast\PROSPERI_EPMFast.iOS\Views\ProjectDetailsView.cs:22 
at (wrapper managed-to-native) ObjCRuntime.Messaging:IntPtr_objc_msgSendSuper (intptr,intptr)
at UIKit.UITabBarController..ctor () [0x0003b] in /Users/builder/data/lanes/3412/3cf8aaed/source/maccore/src/build/ios/native/UIKit/UITabBarController.g.cs:54 
at MvvmCross.Platform.iOS.Views.MvxEventSourceTabBarController..ctor () [0x00000] in C:\vcs\git\MvvmCross\MvvmCross\Platform\iOS\Views\MvxEventSourceTabBarController.cs:20 
at MvvmCross.iOS.Views.MvxTabBarViewController..ctor () [0x00000] in C:\vcs\git\MvvmCross\MvvmCross\iOS\iOS\Views\MvxTabBarViewController.cs:20 
at MvvmCross.iOS.Views.MvxTabBarViewController`1[TViewModel]..ctor () [0x00000] in C:\vcs\git\MvvmCross\MvvmCross\iOS\iOS\Views\MvxTabBarViewController.cs:56 
at PROSPERI_EPMFast.iOS.Views.ProjectDetailsView..ctor () <0x1b486900 + 0x0002b> in <filename unknown>:0 
at (wrapper managed-to-native) System.Reflection.MonoCMethod:InternalInvoke (System.Reflection.MonoCMethod,object,object[],System.Exception&)
at System.Reflection.MonoCMethod.InternalInvoke (System.Object obj, System.Object[] parameters) [0x00002] in /Users/builder/data/lanes/3412/3cf8aaed/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/mcs/class/corlib/System.Reflection/MonoMethod.cs:644 

1 个答案:

答案 0 :(得分:2)

为了完成:https://stackoverflow.com/a/30283563/6143949

  

我猜这里的问题将是具体的方式   构造了TabBarViewController。

     

ViewDidLoad是一个虚拟方法,第一次调用它   访问视图。

     

在TabBarViewController的情况下,这发生在iOS基础上   视图构造函数 - 即它在类本身具有它之前发生   构造函数叫。

     

我找到的唯一方法是添加一个检查   ViewDidLoad中的情况,并再次调用ViewDidLoad   在类构造函数中。

     

你可以在行动N-25中看到这一点 -   https://github.com/MvvmCross/NPlus1DaysOfMvvmCross/blob/976ede3aafd3a7c6e06717ee48a9a45f08eedcd0/N-25-Tabbed/Tabbed.Touch/Views/FirstView.cs#L17

     

类似的东西:

public class MainView : MvxTabBarViewController
{
    private bool _constructed;

    public MainView()
    {
            _constructed = true;

            // need this additional call to ViewDidLoad because UIkit creates the view before the C# hierarchy has been constructed
            ViewDidLoad();
    }

    public override void ViewDidLoad()
    {
        if (!_constructed)
            return;

        base.ViewDidLoad();

        var vm = (MainViewModel)this.ViewModel;
        if (vm == null)
            return;
    }
}

Stuart提供的解决方案(https://stackoverflow.com/users/373321/stuart