MVVMCross:是否可以将Storyboard与ICommand导航一起使用?

时间:2013-06-21 22:09:44

标签: xamarin.ios storyboard mvvmcross

我花了最近几天试图想办法绕过警告:

  

mvx:警告:8.93异常屏蔽MissingMethodException:找不到类型为FCX.iOS.TimesheetView的默认构造函数         在System.Activator.CreateInstance(System.Type type,Boolean nonPublic)[0x00094] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System/Activator.cs:326     在/Developer/MonoTouch/Source/mono/mcs/class/corlib/System/Activator.cs:222中的System.Activator.CreateInstance(System.Type type)[0x00000]     在Cirrious.MvvmCross.Touch.Views.MvxTouchViewsContainer.CreateView(Cirrious.MvvmCross.ViewModels.MvxViewModelRequest request)[0x00000] in:0     在Cirrious.MvvmCross.Touch.Views.MvxCanCreateTouchViewExtensionMethods.CreateViewControllerFor(IMvxCanCreateTouchView视图,Cirrious.MvvmCross.ViewModels.MvxViewModelRequest请求)[0x00000] in:0     在Cirrious   .MvvmCross.Touch.Views.Presenters.MvxTouchViewPresenter.Show(Cirrious.MvvmCross.ViewModels.MvxViewModelRequest request)[0x00000] in:0     在Cirrious.MvvmCross.Touch.Views.MvxTouchViewDispatcher +<> c__DisplayClass4.b__3()[0x00000] in:0     在Cirrious.CrossCore.Core.MvxMainThreadDispatcher.ExceptionMaskedAction(System.Action action)[0x00000] in:0

导航正在寻找这个构造函数:

    public TimesheetView ()
    {
    }

当我想要使用这个构造函数时(出于故事板目的):

    public TimesheetView (IntPtr handle) : base (handle)
    {
    }

我一直在尝试将按钮从一个视图绑定到以下ICommand:

    private MvxCommand _NewTimesheetCommand;
    public ICommand NewTimesheetCommand
    {
        get
        {
            _NewTimesheetCommand =  _NewTimesheetCommand ?? new MvxCommand(() => {
                ShowViewModel<TimesheetViewModel>(new TimesheetViewModel.Parameters { Mode = TimesheetViewModel.ModeEnum.ADD });
            });
            return _NewTimesheetCommand;
        }
    }

在查看了许多StackOverFlow问题之后,我遇到了这个问题,但几乎听起来使用故事板需要我使用segues(换句话说,没有办法使用ICommand来改变我的视图)。

Does MvvmCross support storyboards

我的主要问题:是否可以使用故事板并使用viewmodel更改视图? (而不是使用视图中的segues)

2 个答案:

答案 0 :(得分:2)

嗯,我刚刚实施了斯图尔特所说的话。效果很好。 (请记住,在视图模型中使用ShowViewModel导航时,segue是无用的)

using System;
using Cirrious.MvvmCross.Touch.Views.Presenters;
using MonoTouch.UIKit;
using MonoTouch.Foundation;     
using Cirrious.MvvmCross.Touch.Views;
using Cirrious.MvvmCross.ViewModels;

 namespace DigitalCatalog.UI.Touch
 {
   public class StoryBoardTouchViewPresenter : MvxTouchViewPresenter
  {
    public static UIStoryboard Storyboard = null;


    public StoryBoardTouchViewPresenter (UIApplicationDelegate applicationDelegate, UIWindow window, string storyboardName, NSBundle StoryboardBundleOrNull = null) : base(applicationDelegate, window)
    {
        Storyboard = UIStoryboard.FromName (storyboardName, StoryboardBundleOrNull);
    }

    public override void Show (IMvxTouchView view)
    {
        MvxViewController sbView = null;

        try{
            sbView = (MvxViewController) Storyboard.InstantiateViewController (view.Request.ViewModelType.Name.Replace("Model", ""));
        }catch(Exception e){
            Console.WriteLine ("Failed to find storyboard view, did you forget to set the Storyboard ID to the ViewModel class name without the Model suffix ?" + e);
        }

        sbView.Request = view.Request;

        base.Show (sbView);
    }

}
 }

现在你要做的就是像这样设置AppDelegate:

public override void FinishedLaunching (UIApplication application)
    {


        StoryBoardTouchViewPresenter sbPresenter = new StoryBoardTouchViewPresenter(this, Window,"MainStoryboard_iPad");


        var setup = new Setup(this,sbPresenter);
        setup.Initialize();

        var startup = Mvx.Resolve<IMvxAppStart>();
        startup.Start();


        sbPresenter.MasterNavigationController.NavigationBar.Translucent = false;

        sbPresenter.MasterNavigationController.SetNavigationBarHidden(false, false);

    }

最后记住在故事板中设置每个视图一个带有“类别名称”的故事板ID!遗憾的是,没有任何其他方法可以使用UIStoryboard类获取视图,只能通过使用Storyboard ID来获取它

答案 1 :(得分:0)

有很多方法可以加载`UiViewController。从故事板 - 例如,见load view form StoryBoard that does not have a Segue

如果要在mvvmcross中使用此自定义加载,则可以覆盖IMvxTouchViewCreator以使其使用此类故事板加载,或者您可以覆盖presenter以便加载故事板直接观看。

总的来说,如果你这样做的话,感觉就像是在与故事板作斗争 - 几乎所有的故事板导航似乎都是基于segue的。考虑到这一点,您可以做的另一件事是实现自定义演示者并让演示者将ShowViewModel请求转换为performSegueWithIdentifier个调用。