3

I am trying to write an MvvmCross app using StoryBoards. I know there are similar questions, but I have followed the solutions and I cannot get it to work. I have referenced one of the solutions I have tried in this question.

I'll explain what I have done from the beginning, hopefully this will help in the diagnosis of my problem

  1. Create a project using the the Universal iOS Single View App in Visual Studio.
  2. I do the standard MvvmCross setup, adding nuget, updating AppDelegate etc.
  3. I get it to compile.
  4. I add a new ViewController to the iPhone storyboard. I call it LogonViewController. I set the Class, Storyboard ID and Restoration ID to LogonViewController. The LogonViewController class is generated. I change it to derive it from MvxViewController
  5. I move the entry arrow from the RootViewController (the view controller on the storyboard when it was initially created) to point to the LogonViewController. I leave the RootViewController on the storyboard
  6. I Change the LogonViewController class to derive from MvxViewController and set the Register attribute to LogonView eg

    [Register ("LogonView")]
    partial class LogonViewController
    
  7. I add a label to the LogonViewController just as something to display.

  8. I create a custom container derived from MvxTouchViewsContainers as per the post in

MVVMCross support for Xamarin.iOS Storyboards

The problem is that when the overridden method (shown below) is called in the custom container I get An invalid cast exception as it cannot cast a UIKit.UIViewController to a IMvxTouchView

I also get an arithmetic overflow exception

protected override IMvxTouchView CreateViewOfType(Type viewType, MvxViewModelRequest request)
{
    return (IMvxTouchView)UIStoryboard.FromName("MyStoryBoard", null)


    .InstantiateViewController(viewType.Name);
}

In the trace log I get the following errors

2015-01-28 18:12:09.833 MyApp[3743:68927] mvx:Diagnostic:  8.61 Setup: LastChance start
[0:] mvx:Diagnostic:  8.61 Setup: LastChance start
[0:] 
2015-01-28 18:12:10.247 MyApp[3743:68927] mvx:Diagnostic:  9.05 Setup: Secondary end
[0:] mvx:Diagnostic:  9.05 Setup: Secondary end
[0:] 
2015-01-28 18:12:10.647 MyApp[3743:68927] mvx:Diagnostic:  9.43 Showing ViewModel LogonViewModel
[0:] mvx:Diagnostic:  9.43 Showing ViewModel LogonViewModel
[0:] 
2015-01-28 18:12:11.049 MyApp[3743:68927] TouchNavigation:Diagnostic:  9.83 Navigate requested
[0:] TouchNavigation:Diagnostic:  9.83 Navigate requested
2015-01-28 18:12:11.254 MyApp[3743:68927] Unknown class LogonViewController in Interface Builder file.
2015-01-28 18:12:23.962 MyApp[3743:68927] -[UIViewController bottomLayoutGuide]: guide not available before the view controller's view is loaded
System.OverflowException: Arithmetic operation resulted in an overflow.
   at Mono.Debugging.Soft.SoftDebuggerAdaptor.TargetObjectToObject(EvaluationContext ctx, Object obj)
   at Mono.Debugging.Evaluation.ExpressionEvaluator.TargetObjectToExpression(EvaluationContext ctx, Object obj)
   at Mono.Debugging.Evaluation.ObjectValueAdaptor.CreateObjectValueImpl(EvaluationContext ctx, IObjectValueSource source, ObjectPath path, Object obj, ObjectValueFlags flags)
   at Mono.Debugging.Evaluation.ObjectValueAdaptor.CreateObjectValue(EvaluationContext ctx, IObjectValueSource source, ObjectPath path, Object obj, ObjectValueFlags flags)
System.OverflowException: Arithmetic operation resulted in an overflow.
   at Mono.Debugging.Soft.SoftDebuggerAdaptor.TargetObjectToObject(EvaluationContext ctx, Object obj)
   at Mono.Debugging.Evaluation.ExpressionEvaluator.TargetObjectToExpression(EvaluationContext ctx, Object obj)
   at Mono.Debugging.Evaluation.ObjectValueAdaptor.CreateObjectValueImpl(EvaluationContext ctx, IObjectValueSource source, ObjectPath path, Object obj, ObjectValueFlags flags)
   at Mono.Debugging.Evaluation.ObjectValueAdaptor.CreateObjectValue(EvaluationContext ctx, IObjectValueSource source, ObjectPath path, Object obj, ObjectValueFlags flags)
System.OverflowException: Arithmetic operation resulted in an overflow.
   at Mono.Debugging.Soft.SoftDebuggerAdaptor.TargetObjectToObject(EvaluationContext ctx, Object obj)
   at Mono.Debugging.Evaluation.ExpressionEvaluator.TargetObjectToExpression(EvaluationContext ctx, Object obj)
   at Mono.Debugging.Evaluation.ObjectValueAdaptor.CreateObjectValueImpl(EvaluationContext ctx, IObjectValueSource source, ObjectPath path, Object obj, ObjectValueFlags flags)
   at Mono.Debugging.Evaluation.ObjectValueAdaptor.CreateObjectValue(EvaluationContext ctx, IObjectValueSource source, ObjectPath path, Object obj, ObjectValueFlags flags)
Unhandled Exception:

System.InvalidCastException: Unable to cast object of type 'UIKit.UIViewController' to type 'Cirrious.MvvmCross.Touch.Views.IMvxTouchView'.

I'm at a loss to know what I am doing wrong here. Has anyone got any ideas? This is the versions of software installed

MvvmCross 3.5.0 Visual Studio 2012 Update 4, Xamarin Universal Installer v3.5.0.0 Xamarin Studio 5.7 v5.7.0.661 Xamarin v3.9.236.0

Update

I took EShy's advice and added the controller and named it LogonView, however I still get a problem where the LogonViewModel is not getting contructed. The log is shown below. Any ideas?

2015-01-29 11:31:33.579 MyApp[12631:273902] mvx:Diagnostic:286.77 Message = [Failed to construct and initialize ViewModel for type MyApp.Core.ViewModels.LogonViewModel from locator MvxDefaultViewModelLocator - check InnerException for more information]
[0:] mvx:Diagnostic:286.77 Message = [Failed to construct and initialize ViewModel for type MyApp.Core.ViewModels.LogonViewModel from locator MvxDefaultViewModelLocator - check InnerException for more information]
[0:] 
2015-01-29 11:31:33.985 MyApp[12631:273902] mvx:Diagnostic:287.17 Stack Trace = [  at Cirrious.MvvmCross.ViewModels.MvxViewModelLoader.LoadViewModel (Cirrious.MvvmCross.ViewModels.MvxViewModelRequest request, IMvxBundle savedState, IMvxViewModelLocator viewModelLocator) [0x00000] in <filename unknown>:0 
  at Cirrious.MvvmCross.ViewModels.MvxViewModelLoader.LoadViewModel (Cirrious.MvvmCross.ViewModels.MvxViewModelRequest request, IMvxBundle savedState) [0x00000] in <filename unknown>:0 
  at Cirrious.MvvmCross.Touch.Views.MvxViewControllerExtensionMethods.LoadViewModel (IMvxTouchView touchView) [0x00000] in <filename unknown>:0 
  at Cirrious.MvvmCross.Views.MvxViewExtensionMethods.OnViewCreate (IMvxView view, System.Func`1 viewModelLoader) [0x00000] in <filename unknown>:0 
  at Cirrious.MvvmCross.Touch.Views.MvxViewControllerExtensionMethods.OnViewCreate (IMvxTouchView touchView) [0x00000] in <filename unknown>:0 
  at Cirrious.MvvmCross.Touch.Views.MvxViewControllerAdapter.HandleViewDidLoadCalled 
[0:] mvx:Diagnostic:287.17 Stack Trace = [  at Cirrious.MvvmCross.ViewModels.MvxViewModelLoader.LoadViewModel (Cirrious.MvvmCross.ViewModels.MvxViewModelRequest request, IMvxBundle savedState, IMvxViewModelLocator viewModelLocator) [0x00000] in <filename unknown>:0 
  at Cirrious.MvvmCross.ViewModels.MvxViewModelLoader.LoadViewModel (Cirrious.MvvmCross.ViewModels.MvxViewModelRequest request, IMvxBundle savedState) [0x00000] in <filename unknown>:0 
  at Cirrious.MvvmCross.Touch.Views.MvxViewControllerExtensionMethods.LoadViewModel (IMvxTouchView touchView) [0x00000] in <filename unknown>:0 
  at Cirrious.MvvmCross.Views.MvxViewExtensionMethods.OnViewCreate (IMvxView view, System.Func`1 viewModelLoader) [0x00000] in <filename unknown>:0 
  at Cirrious.MvvmCross.Touch.Views.MvxViewControllerExtensionMethods.OnViewCreate (IMvxTouchView touchView) [0x00000] in <filename unknown>:0 
  at Cirrious.MvvmCross.Touch.Views.MvxViewControllerAdapter.HandleViewDidLoadCalled (System.Object sender, System.EventArgs e) [0x00000] in <filename unknown>:0 
  at (wrapper delegate-invoke) <Module>:invoke_void_object_EventArgs (object,System.EventArgs)
  at Cirrious.CrossCore.Core.MvxDelegateExtensionMethods.Raise (System.EventHandler eventHandler, System.Object sender) [0x00000] in <filename unknown>:0 
  at Cirrious.CrossCore.Touch.Views.MvxEventSourceViewController.ViewDidLoad () [0x00000] in <filename unknown>:0 
  at (wrapper managed-to-native) UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
  at UIKit.UIApplication.Main (System.String[] args, IntPtr principal, IntPtr delegate) [0x00005] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:62 
  at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x00038] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:46 
  at MyApp.iOS.Application.Main (System.String[] args) [0x00002] in c:\MyApp.iOS\Main.cs:21 ]
(System.Object sender, System.EventArgs e) [0x00000] in <filename unknown>:0 
  at (wrapper delegate-invoke) <Module>:invoke_void_object_EventArgs (object,System.EventArgs)
  at Cirrious.CrossCore.Core.MvxDelegateExtensionMethods.Raise (System.EventHandler eventHandler, System.Object sender) [0x00000] in <filename unknown>:0 
  at Cirrious.CrossCore.Touch.Views.MvxEventSourceViewController.ViewDidLoad () [0x00000] in <filename unknown>:0 
  at (wrapper managed-to-native) UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
  at UIKit.UIApplication.Main (System.String[] args, IntPtr principal, IntPtr delegate) [0x00005] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:62 
  at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x00038] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:46 
  at MyApp.iOS.Application.Main (System.String[] args) [0x00002] in c:\MyApp\
MyApp.iOS\Main.cs:21 ]
[0:] 
2015-01-29 11:31:34.393 MyApp[12631:273902] mvx:Diagnostic:287.58 Inner Exception message = [Problem creating viewModel of type LogonViewModel]
[0:] mvx:Diagnostic:287.58 Inner Exception message = [Problem creating viewModel of type LogonViewModel]
Community
  • 1
  • 1
rideintothesun
  • 1,628
  • 2
  • 12
  • 29
  • if you store the ref returned from `UIStoryboard.FromName("MyStoryBoard", null).InstantiateViewController(viewType.Name);` in a variable, then use the watch window, what type of controller is being returned? – Stuart Jan 29 '15 at 09:38
  • I'll do that Stuart, might be a while, having a few issues. Do I also have to add the storyboard I am using into the project settings? – rideintothesun Jan 29 '15 at 10:46
  • HI Stuart, I did as EShy suggested and added a view controller to the storyboard and named it LogonView instead of LogonViewController. The type returned is now an MvxViewController. However I am still getting the exception That it cannot construct the LogonViewModel. I have added it to the original question as an update – rideintothesun Jan 29 '15 at 11:32
  • I see is the error `Unknown class LogonViewController in Interface Builder file` - try solving that error first? – Stuart Jan 29 '15 at 11:37
  • Hi Stuart, That error has gone now since I set the ViewController to be named LogonView. The problem now is that the LogonViewModel fails to be created. I have added logs on the questions, so it is clearer to read – rideintothesun Jan 29 '15 at 11:53
  • what's your LogonViewModel ctor look like? Does it get called? Is there an innerexception you can look at? – Stuart Jan 29 '15 at 12:39
  • HI Stuart, Your help solved it. The problem was that a service injected into the LogonViewModel used the MvvmCross Messenger plugin. I had not added the plugin via nuget to the project. The exception that informed me of this was an inner exception of an inner exception. I should have dug deeper. Thanks again to you Stuart for this help and MvvmCross goodness in general. Thanks also to EShy for the naming help. – rideintothesun Jan 29 '15 at 13:32

2 Answers2

1

You should name your viewcontroller in the storyboard LogonView and not LogonViewController. That's the viewType.Name that MvvmCross is looking for.

EShy
  • 297
  • 4
  • 8
0

The problem was that a service injected into the LogonViewModel used the MvvmCross Messenger plugin. I had not added the plugin via nuget to the project. The exception that informed me of this was an inner exception of an inner exception. I should have dug deeper. Thanks again to you Stuart for this help and MvvmCross goodness in general. Thanks also to EShy for the naming help.

animuson
  • 53,861
  • 28
  • 137
  • 147
rideintothesun
  • 1,628
  • 2
  • 12
  • 29