我知道为了实现这一点,我需要创建一个自定义演示者,并通过覆盖InitializeViewLookup
方法手动将ViewModel映射到我的视图。我在Android上成功做到了这一点,到目前为止一切正常,但我似乎无法在iOS上做到这一点。这就是我的尝试:
public override void Show(MvxViewModelRequest request)
{
// check if there are any presentation values
if (request.PresentationValues != null)
{
// if yes, check if one of them is SelectedView
if (request.PresentationValues.ContainsKey(SingletonViewModelLocator.SelectedView))
{
UIViewController viewController;
switch (request.PresentationValues[SingletonViewModelLocator.SelectedView])
{
// The ViewModel requested the First View, load that one
case SingletonViewModelLocator.FirstViewValue:
viewController = new FirstView();
MasterNavigationController.PushViewController(viewController, true);
return;
// The ViewModel requested the Second View, load that one
case SingletonViewModelLocator.SecondViewValue:
viewController = new SecondView();
MasterNavigationController.PushViewController(viewController, true);
return;
// wrong view requested
default:
throw (new InvalidEnumArgumentException(request.PresentationValues[SingletonViewModelLocator.SelectedView] +
" does not exist."));
}
}
}
// otherwise run the default method which means 1 ViewModel is mapped to 1 View
base.Show(request);
}
此处InitializeViewLookup
:
protected override void InitializeViewLookup()
{
var container = Mvx.Resolve<IMvxViewsContainer>();
container.Add(typeof(MainViewModel), typeof(MainView));
// TheViewModel is mapped to two Views
container.Add(typeof(TheViewModel), typeof(FirstView));
container.Add(typeof(TheViewModel), typeof(SecondView));
}
这使得&#34;对象引用未设置为对象的实例&#34;导航发生时,ViewDidLoad
方法上Mvx库内部的异常。
仅供参考,以下是我在 Android 上进行操作的原因。
public override void Show(MvxViewModelRequest request)
{
// check if there are any presentation values
if (request.PresentationValues != null)
{
// if yes, check if one of them is SelectedView
if (request.PresentationValues.ContainsKey(SingletonViewModelLocator.SelectedView))
{
var activity = Activity;
Intent intent;
switch (request.PresentationValues[SingletonViewModelLocator.SelectedView])
{
// The ViewModel requested the First View, load that one
case SingletonViewModelLocator.FirstViewValue:
intent = new Intent(activity, typeof (FirstView));
Show(intent);
return;
// The ViewModel requested the Second View, load that one
case SingletonViewModelLocator.SecondViewValue:
intent = new Intent(activity, typeof (SecondView));
Show(intent);
return;
// wrong view requested
default:
throw (new InvalidEnumArgumentException(request.PresentationValues[SingletonViewModelLocator.SelectedView] +
" does not exist."));
}
}
}
// otherwise run the default method which means 1 ViewModel is mapped to 1 View
base.Show(request);
}
修改
这是堆栈跟踪:
0x0 in Cirrious.MvvmCross.ViewModels.MvxViewModelLoader.LoadViewModel
0x65 in Cirrious.MvvmCross.Touch.Views.MvxViewControllerExtensionMethods.LoadViewModel
0x13 in Cirrious.MvvmCross.Views.MvxViewExtensionMethods.OnViewCreate
0xE in Cirrious.MvvmCross.Touch.Views.MvxViewControllerExtensionMethods.OnViewCreate
0x7 in Cirrious.MvvmCross.Touch.Views.MvxViewControllerAdapter.HandleViewDidLoadCalled
0xB in Cirrious.CrossCore.Core.MvxDelegateExtensionMethods.Raise
0xD in Cirrious.CrossCore.Touch.Views.MvxEventSourceViewController.ViewDidLoad
在p中的Demo.iOS.FirstView.ViewDidLoad中的0x2:[path] \ View \ FirstView.cs:34,-1
UIKit.UIApplication.UIApplicationMain中的0xA6 位于/Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:62,4的UIKit.UIApplication.Main中的0xB UIKit.UIApplication.Main中的0x3B位于/Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:46,5
Demo.iOS.Application.Main中的0x8位于c:[path] \ Main.cs:17,-1
答案 0 :(得分:1)
Mvx Touch应用程序中的默认容器使用以下代码创建视图:
CurrentRequest = request;
var viewType = GetViewType(request.ViewModelType);
if (viewType == null)
throw new MvxException("View Type not found for " + request.ViewModelType);
var view = CreateViewOfType(viewType, request);
view.Request = request;
return view;
每个View
然后使用隐藏在ViewModel
中的说明加载/找到自己的Request
。
如果Request
为空,则Mvx默认使用某些启发式方法,根据使用View
类名的约定创建类型的默认ViewModel。
在您的情况下,我认为最好的解决方案是在ViewController上设置Request
属性 - 例如
case SingletonViewModelLocator.SecondViewValue:
viewController = new SecondView() { Request = request };
MasterNavigationController.PushViewController(viewController, true);
return;
但是,您也可以通过在SecondView
中提供有关预期的ViewModel类型的提示来执行此操作...您可以通过使用类型覆盖ViewModel
属性来执行此操作,方法是继承来自MvxViewController<T>
,为视图模型类型(MvxViewFor
)提供属性提示,或者在Setup
期间添加一些特殊查找
注意 - 你的问题也告诉我你在ViewModel
查询方面做了一些单身魔术,所以你可能需要调整这个答案来匹配任何东西......