I am using the latest version of Xamarin.Forms. My page has a ListView which shows ViewCells containing an Image. Now I would like to react to a tap on these images. Therefore, I added this code
<Image Grid.Column="1" Source="download_cloud.png" WidthRequest="32" HeightRequest="32">
<Image.GestureRecognizers>
<TapGestureRecognizer NumberOfTapsRequired="1" Tapped="SynchronizeItem_Clicked"/>
</Image.GestureRecognizers>
</Image>
This works flawless on Android. Sadly, this is not working on iOS but causes an exception (Object reference not set to an instance). The strange thing is, that when I add this TapGestureRecognizer to a Label which is displayed next to the Image everything is working perfectly.
So, is this a bug in Xamarin.Forms on iOS or am I doing something wrong?
Edit: This is the stacktrace:
Unhandled Exception:
System.NullReferenceException: Object reference not set to an instance of an object
at Xamarin.Forms.Platform.iOS.EventTracker.LoadRecognizers () [0x0005d] in D:\agent\_work\1\s\Xamarin.Forms.Platform.iOS\EventTracker.cs:373
at Xamarin.Forms.Platform.iOS.EventTracker.OnElementChanged (System.Object sender, Xamarin.Forms.Platform.iOS.VisualElementChangedEventArgs e) [0x0004e] in D:\agent\_work\1\s\Xamarin.Forms.Platform.iOS\EventTracker.cs:439
at Xamarin.Forms.Platform.iOS.VisualElementRenderer`1[TElement].OnElementChanged (Xamarin.Forms.Platform.iOS.ElementChangedEventArgs`1[TElement] e) [0x00020] in D:\agent\_work\1\s\Xamarin.Forms.Platform.iOS\VisualElementRenderer.cs:279
at Xamarin.Forms.Platform.iOS.ViewRenderer`2[TView,TNativeView].OnElementChanged (Xamarin.Forms.Platform.iOS.ElementChangedEventArgs`1[TElement] e) [0x00000] in D:\agent\_work\1\s\Xamarin.Forms.Platform.iOS\ViewRenderer.cs:85
at Xamarin.Forms.Platform.iOS
.ImageRenderer.<>n__0 (Xamarin.Forms.Platform.iOS.ElementChangedEventArgs`1[TElement] e) <0x13780f3f0 + 0x0005a> in <13d193f5a21b4e309afc67e0a5508db5>:0
at Xamarin.Forms.Platform.iOS.ImageRenderer+<OnElementChanged>d__2.MoveNext () [0x000d6] in D:\agent\_work\1\s\Xamarin.Forms.Platform.iOS\Renderers\ImageRenderer.cs:70
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Library/Frameworks/Xamarin.iOS.framework/Versions/11.6.1.2/src/mono/mcs/class/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:152
at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__6_0 (System.Object state) [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/11.6.1.2/src/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:1018
at UIKit.UIKitSynchronizationContext+<Post>c__AnonStorey0.<>m__0 () [0x00000] in /Users
/builder/data/lanes/5665/6857dfcc/source/xamarin-macios/src/UIKit/UIKitSynchronizationContext.cs:24
at Foundation.NSAsyncActionDispatcher.Apply () [0x00000] in /Users/builder/data/lanes/5665/6857dfcc/source/xamarin-macios/src/Foundation/NSAction.cs:163
--- End of stack trace from previous location where exception was thrown ---
at (wrapper managed-to-native) UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
at UIKit.UIApplication.Main (System.String[] args, System.IntPtr principal, System.IntPtr delegate) [0x00005] in /Users/builder/data/lanes/5665/6857dfcc/source/xamarin-macios/src/UIKit/UIApplication.cs:79
at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x00038] in /Users/builder/data/lanes/5665/6857dfcc/source/xamarin-macios/src/UIKit/UIApplication.cs:63
at SMSIP2.iOS.Application.Main (System.String[] args) [0x00001] in C:\Users\Roland\Source\Repos\SMSIP2\SMSIP2\SMSIP2.iOS\Main.cs:12
2018-01-28 10:06:25.613 SMSIP2.iOS[73968:6382644] Unhandled managed exception:
Object reference not set to an instance of an object (System.NullReferenceException)
at Xamarin.Forms.Platform.iOS.EventTracker.LoadRecognizers () [0x0005d] in D:\agent\_work\1\s\Xamarin.Forms.Platform.iOS\EventTracker.cs:373
at Xamarin.Forms.Platform.iOS.EventTracker.OnElementChanged (System.Object sender, Xamarin.Forms.Platform.iOS.VisualElementChangedEventArgs e) [0x0004e] in D:\agent\_work\1\s\Xamarin.Forms.Platform.iOS\EventTracker.cs:439
at Xamarin.Forms.Platform.iOS.VisualElementRenderer`1[TElement].OnElementChanged (Xamarin.Forms.Platform.iOS.ElementChangedEventArgs`1[TElement] e) [0x00020] in D:\agent\_work\1\s\Xamarin.Forms.Platform.iOS\VisualElementRenderer.cs:279
at Xamarin.Forms.Platform.iOS.ViewRenderer`2[TView,TNativeView].OnElementChanged (Xamarin.Forms.Platform.iOS.ElementChangedEventArgs`1[TElement] e) [0x00000] in D:\agent\_work\1\s\Xamarin.Forms.Platform.iOS\ViewRenderer.cs:85
at Xamarin.Forms.Plat
form.iOS.ImageRenderer.<>n__0 (Xamarin.Forms.Platform.iOS.ElementChangedEventArgs`1[TElement] e) <0x13780f3f0 + 0x0005a> in <13d193f5a21b4e309afc67e0a5508db5>:0
at Xamarin.Forms.Platform.iOS.ImageRenderer+<OnElementChanged>d__2.MoveNext () [0x000d6] in D:\agent\_work\1\s\Xamarin.Forms.Platform.iOS\Renderers\ImageRenderer.cs:70
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Library/Frameworks/Xamarin.iOS.framework/Versions/11.6.1.2/src/mono/mcs/class/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:152
at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__6_0 (System.Object state) [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/11.6.1.2/src/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:1018
at UIKit.UIKitSynchronizationContext+<Post>c__AnonStorey0.<>m__0 () [0x00000] i
n /Users/builder/data/lanes/5665/6857dfcc/source/xamarin-macios/src/UIKit/UIKitSynchronizationContext.cs:24
at Foundation.NSAsyncActionDispatcher.Apply () [0x00000] in /Users/builder/data/lanes/5665/6857dfcc/source/xamarin-macios/src/Foundation/NSAction.cs:163
--- End of stack trace from previous location where exception was thrown ---
at (wrapper managed-to-native) UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
at UIKit.UIApplication.Main (System.String[] args, System.IntPtr principal, System.IntPtr delegate) [0x00005] in /Users/builder/data/lanes/5665/6857dfcc/source/xamarin-macios/src/UIKit/UIApplication.cs:79
at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x00038] in /Users/builder/data/lanes/5665/6857dfcc/source/xamarin-macios/src/UIKit/UIApplication.cs:63
at SMSIP2.iOS.Application.Main (System.String[] args) [0x00001] in C:\Users\Roland\Source\Repos\SMSIP2\SMSIP2\SMSIP2.iOS\Main.cs:12
2018-01-28 10
and this is the callback:
void SynchronizeItem_Clicked(object sender, EventArgs ee)
{
}
Edit2: When I use this code somewhere else and not in the ListView it is working on iOS, too.
Edit3: I fixed this problem now - but the solution is very strange and I do not know at all, why it is working. But here we go: My CellView contained a Grid in which I wanted to place my Image. This is not working. What is working instead is: place the Image inside a StackLayout and place this StackLayout in the Grid. This looks just like the code without the additional StackLayout and suddenly the GestureRecognizer works. Can someone tell me why this is happening?
Edit4: Apparently this is not a great solution as this Command of the GestureListener is now also executed sometimes when you click on the ViewCell instead of the Image. So this is no real solution.
Related
I have a ListView, whose contents I refresh with a button click. ListView is bound to ObservableCollection<MyClass> in view model.
However, I get null reference exception in iOS on data refresh (but it works fine in Android).
The exception is thrown at Main method in iOS application.
// NullReferenceException thrown here.
UIApplication.Main(args, null, "AppDelegate");
The following is the stack trace.
at Xamarin.Forms.Platform.iOS.EventTracker.LoadRecognizers () [0x0005d] in :0
at Xamarin.Forms.Platform.iOS.EventTracker.OnElementChanged (System.Object sender, Xamarin.Forms.Platform.iOS.VisualElementChangedEventArgs e) [0x0004e] in :0
at Xamarin.Forms.Platform.iOS.VisualElementRenderer1[TElement].OnElementChanged (Xamarin.Forms.Platform.iOS.ElementChangedEventArgs1[TElement] e) [0x0002c] in :0
at Xamarin.Forms.Platform.iOS.ViewRenderer2[TView,TNativeView].OnElementChanged (Xamarin.Forms.Platform.iOS.ElementChangedEventArgs1[TElement] e) [0x00000] in :0
at Xamarin.Forms.Platform.iOS.ImageRenderer.<>n__0 (Xamarin.Forms.Platform.iOS.ElementChangedEventArgs`1[TElement] e) [0x00000] in :0
at Xamarin.Forms.Platform.iOS.ImageRenderer+d__2.MoveNext () [0x000d6] in :0
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Library/Frameworks/Xamarin.iOS.framework/Versions/11.6.1.2/src/mono/mcs/class/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:152
at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.b__6_0 (System.Object state) [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/11.6.1.2/src/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:1018
at UIKit.UIKitSynchronizationContext+c__AnonStorey0.<>m__0 () [0x00000] in /Users/builder/data/lanes/5665/6857dfcc/source/xamarin-macios/src/UIKit/UIKitSynchronizationContext.cs:24
at Foundation.NSAsyncActionDispatcher.Apply () [0x00000] in /Users/builder/data/lanes/5665/6857dfcc/source/xamarin-macios/src/Foundation/NSAction.cs:163
at (wrapper managed-to-native) UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
at UIKit.UIApplication.Main (System.String[] args, System.IntPtr principal, System.IntPtr delegate) [0x00005] in /Users/builder/data/lanes/5665/6857dfcc/source/xamarin-macios/src/UIKit/UIApplication.cs:79
at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x00038] in /Users/builder/data/lanes/5665/6857dfcc/source/xamarin-macios/src/UIKit/UIApplication.cs:63
at Omers.MyTeam.Mobile.iOS.Application.Main (System.String[] args) [0x00001] in /Users/user/Projects/proj/Company.Proj.Mobile/Company.Proj.Mobile.iOS/Main.cs:12
The following is the offending code.
<ListView ItemsSource="{Binding PeopleData}" HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid>
...
<Image VerticalOptions="Center"
Source="phone_icon"
WidthRequest="45"
HeightRequest="45"
Margin="0,0,5,0"
Opacity="0.27">
<!--<Image.GestureRecognizers>
<TapGestureRecognizer NumberOfTapsRequired="1"
Command="{Binding Source={x:Reference PeoplePage}, Path=BindingContext.CallPersonCommand}"
CommandParameter="{Binding .}"></TapGestureRecognizer>
</Image.GestureRecognizers>-->
</Image>
<Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
The TapGestureRecognizer for the Image causes the exception if it is uncommented. The Content Page is named PeoplePage.
The first time ListView is populated is on application start up, without errors.
I click a button to repopulate ListView the second time - works fine. I click a button again to refresh ListView - it errors out.
Clicking button simply refreshes data in ObservableCollection<MyClass> to which ListView is bound.
Any ideas on this are greatly appreciated. Thanks!
I solved the problem as follows.
Before, when I was refreshing data in ObservableCollection<MyClass> I would do it similar to the following.
// PeopleData is ObservableCollection<MyClass>
PeopleData.Clear();
foreach (var person in retrievedFromApiPeople)
{
PeopleData.Add(person);
}
Now, I added a backing field for the PeopleData property and simply assign a new ObservableCollection to the property and raise notification, similar to the following.
private ObservableCollection<MyClass> _peopleData;
public ObservableCollection<MyClass> PeopleData
{
get => _peopleData;
set
{
_peopleData = value;
// INotifyPropertyChanged implementation.
RaisePropertyChanged(() => PeopleData);
}
}
And use it as follows.
PeopleData = retrievedFromApiPeople;
This approach works. Not sure why the other way wasn't working.
Was facing the same issue, but it is solved in the latest version of Xamarin.Forms (2.5.1.444934).
The map is displayed properly with pins etc. However under iOS I'm receiving this error when switching to a different view, even without pins etc. Maybe a configuration issue in Info.plist?
System.NullReferenceException: Object reference not set to an instance of an object
at Xamarin.Forms.GoogleMaps.iOS.MapRenderer.OnElementChanged (Xamarin.Forms.Platform.iOS.ElementChangedEventArgs`1[TElement] e) [0x00069] in <0bdc53fe1bce4b6e878e432cac02c7af>:0
at Xamarin.Forms.Platform.iOS.VisualElementRenderer`1[TElement].SetElement (TElement element) [0x00110] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Platform.iOS\VisualElementRenderer.cs:167
at Xamarin.Forms.Platform.iOS.VisualElementRenderer`1[TElement].Dispose (System.Boolean disposing) [0x0007b] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Platform.iOS\VisualElementRenderer.cs:218
at Xamarin.Forms.Platform.iOS.ViewRenderer`2[TView,TNativeView].Dispose (System.Boolean disposing) [0x00000] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Platform.iOS\ViewRenderer.cs:42
at Xamarin.Forms.GoogleMaps.iOS.MapRenderer.Dispose (System.Boolean disposing) [0x000a8] in <0bdc53fe1bce4b6e878e432cac02c7af>:0
at Foundation.NSObject.Dispose () [0x00000] in /Users/builder/data/lanes/4292/e66c6f19/source/xamarin-macios/src/Foundation/NSObject2.cs:133
at Xamarin.Forms.Platform.iOS.Platform.DisposeModelAndChildrenRenderers (Xamarin.Forms.Element view) [0x00038] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Platform.iOS\Platform.cs:231
at Xamarin.Forms.Platform.iOS.Platform.HandleChildRemoved (System.Object sender, Xamarin.Forms.ElementEventArgs e) [0x00007] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Platform.iOS\Platform.cs:342
at Xamarin.Forms.Element.OnDescendantRemoved (Xamarin.Forms.Element child) [0x00008] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Core\Element.cs:601
at Xamarin.Forms.Element.OnDescendantRemoved (Xamarin.Forms.Element child) [0x00022] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Core\Element.cs:604
I had similar issue but once i updated xamarin.Forms.googlemaps to this version
https://www.nuget.org/packages/Xamarin.Forms.GoogleMaps/1.8.1
After I selected View As -> "Enable Size Classes.." option in the designer UI, I cannot run the project anymore. I am getting this error. Any idea how to fix this ?
MonoTouch.Foundation.MonoTouchException: Objective-C exception thrown.
Name: NSInvalidArgumentException Reason: There doesn't seem to be a
valid compiled storyboard at path
'/private/var/mobile/Containers/Bundle/Application/FF1A6941-B237-41E5-9463-F6E3252A21CB/xbmc_music.app/MainStoryboard.storyboardc'
at MonoTouch.ObjCRuntime.Runtime.ThrowNSException (IntPtr
ns_exception) [0x00000] in
/Users/builder/data/lanes/1799/3c4e832a/source/maccore/src/ObjCRuntime/Runtime.cs:167
at MonoTouch.ObjCRuntime.Runtime.throw_ns_exception (IntPtr exc)
[0x00000] in :0 at (wrapper native-to-managed)
MonoTouch.ObjCRuntime.Runtime:throw_ns_exception (intptr) at
(wrapper managed-to-native)
MonoTouch.UIKit.UIApplication:UIApplicationMain
(int,string[],intptr,intptr) at MonoTouch.UIKit.UIApplication.Main
(System.String[] args, IntPtr principal, IntPtr delegate) [0x00005] in
/Users/builder/data/lanes/1799/3c4e832a/source/maccore/src/UIKit/UIApplication.cs:63
at MonoTouch.UIKit.UIApplication.Main (System.String[] args,
System.String principalClassName, System.String delegateClassName)
[0x0001c] in
/Users/builder/data/lanes/1799/3c4e832a/source/maccore/src/UIKit/UIApplication.cs:46
at xbmc_music.Application.Main (System.String[] args) [0x00035] in
/Users/Apple/Projects/xoxo/xbmc_music/xbmc_music/Main.cs:46
NSInvalidArgumentException: There doesn't seem to be a valid compiled
storyboard at path
'/private/var/mobile/Containers/Bundle/Application/FF1A6941-B237-41E5-9463-F6E3252A21CB/xbmc_music.app/MainStoryboard.
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
Create a project using the the Universal iOS Single View App in Visual Studio.
I do the standard MvvmCross setup, adding nuget, updating AppDelegate etc.
I get it to compile.
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
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
I Change the LogonViewController class to derive from MvxViewController and set the Register attribute to LogonView eg
[Register ("LogonView")]
partial class LogonViewController
I add a label to the LogonViewController just as something to display.
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]
You should name your viewcontroller in the storyboard LogonView and not LogonViewController. That's the viewType.Name that MvvmCross is looking for.
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.
I use MvvmCross for develop a CrossPlatform App.
I work on my Mac and I have not errors when I build my solution.
When I run it... I have this error : failed to find constructor for type Cirrious.MvvmCross.ViewModels.MvxViewModelLoader and highlights base.ViewDidLoad();
Code :
public partial class MainView : MvxViewController
{
static bool UserInterfaceIdiomIsPhone {
get { return UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Phone; }
}
public MainView ()
: base (UserInterfaceIdiomIsPhone ? "MainView_iPhone" : "MainView_iPad", null)
{
}
public override void DidReceiveMemoryWarning ()
{
// Releases the view if it doesn't have a superview.
base.DidReceiveMemoryWarning ();
// Release any cached data, images, etc that aren't in use.
}
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
// Perform any additional setup after loading the view, typically from a nib.
}
It's a default code, I just changed super-class (UIViewController to MvxViewController)
Stacktrace :
Failed to find constructor for type Cirrious.MvvmCross.ViewModels.MvxViewModelLoader
at Cirrious.CrossCore.IoC.MvxSimpleIoCContainer.IoCConstruct (System.Type type) [0x00000] in :0
at Cirrious.CrossCore.IoC.MvxSimpleIoCContainer+ConstructingResolver.Resolve () [0x00000] in :0
at Cirrious.CrossCore.IoC.MvxSimpleIoCContainer.InternalTryResolve (System.Type type, ResolveOptions resolveOptions, System.Object& resolved) [0x00000] in :0
at Cirrious.CrossCore.IoC.MvxSimpleIoCContainer.InternalTryResolve (System.Type type, System.Object& resolved) [0x00000] in :0
at Cirrious.CrossCore.IoC.MvxSimpleIoCContainer.Resolve (System.Type t) [0x00000] in :0
at Cirrious.CrossCore.IoC.MvxSimpleIoCContainer.Resolve[IMvxViewModelLoader] () [0x00000] in :0
at Cirrious.CrossCore.Mvx.Resolve[IMvxViewModelLoader] () [0x00000] in :0
at Cirrious.MvvmCross.Touch.Views.MvxViewControllerExtensionMethods.LoadViewModel (IMvxTouchView touchView) [0x00000] in :0
at Cirrious.MvvmCross.Touch.Views.MvxViewControllerExtensionMethods+<>c_DisplayClass1.b_0 () [0x00000] in :0
at Cirrious.MvvmCross.Views.MvxViewExtensionMethods.OnViewCreate (IMvxView view, System.Func`1 viewModelLoader) [0x00000] in :0
at Cirrious.MvvmCross.Touch.Views.MvxViewControllerExtensionMethods.OnViewCreate (IMvxTouchView touchView) [0x00000] in :0
at Cirrious.MvvmCross.Touch.Views.MvxViewControllerAdapter.HandleViewDidLoadCalled (System.Object sender, System.EventArgs e) [0x00000] in :0
at (wrapper delegate-invoke) :invoke_void_this__object_EventArgs (object,System.EventArgs)
at Cirrious.CrossCore.Core.MvxDelegateExtensionMethods.Raise (System.EventHandler eventHandler, System.Object sender) [0x00000] in :0
at Cirrious.CrossCore.Touch.Views.MvxEventSourceViewController.ViewDidLoad () [0x00000] in :0
at TrainingCatalog.Touch.MainView.ViewDidLoad () [0x00002] in /Users/a_masteruser/Projects/DefaultCollection/_git/HapplyTrainingCatalog/TrainingCatalog.Touch/Views/MainView.cs:30
at (wrapper managed-to-native) MonoTouch.ObjCRuntime.Messaging:void_objc_msgSend (intptr,intptr)
at MonoTouch.UIKit.UIWindow.MakeKeyAndVisible () [0x00008] in /Developer/MonoTouch/Source/monotouch/src/UIKit/.pp-UIWindow.g.cs:129
at TrainingCatalog.Touch.AppDelegate.FinishedLaunching (MonoTouch.UIKit.UIApplication app, MonoTouch.Foundation.NSDictionary options) [0x0003c] in /Users/a_masteruser/Projects/DefaultCollection/_git/HapplyTrainingCatalog/TrainingCatalog.Touch/AppDelegate.cs:21
at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
at MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0004c] in /Developer/MonoTouch/Source/monotouch/src/UIKit/.pp-UIApplication.cs:38
at TrainingCatalog.Touch.Application.Main (System.String[] args) [0x00008] in /Users/a_masteruser/Projects/DefaultCollection/_git/HapplyTrainingCatalog/TrainingCatalog.Touch/Main.cs:17
Failed to find constructor for type Cirrious.MvvmCross.ViewModels.MvxViewModelLoader
From the stack trace, I'm guessing the line that is failing is: https://github.com/MvvmCross/MvvmCross/blob/v3.1/Cirrious/Cirrious.MvvmCross.Touch/Views/MvxViewControllerExtensionMethods.cs#L44
This is looking in IoC for a type which has been registered in setup as:
protected virtual void InitializeViewModelFramework()
{
Mvx.RegisterType<IMvxViewModelLoader, MvxViewModelLoader>();
}
(from https://github.com/MvvmCross/MvvmCross/blob/v3.1/Cirrious/Cirrious.MvvmCross/Platform/MvxSetup.cs#L192)
Looking at MvxViewModelLoader, this is defined in: https://github.com/MvvmCross/MvvmCross/blob/v3.1/Cirrious/Cirrious.MvvmCross/ViewModels/MvxViewModelLoader.cs - so it should have a default public parameterless constructor added by the compiler...
With this in mind...
I'm guessing that maybe Xamarin is stripping out the constructor from your deployed binaries. This might be because of your linker settings - so please check that you have set the linker to link "SDK only". But if that doesn't help then this might be down to some Xamarin optimisation/feature - so you might need to .
As a simple workaround you could try overriding Setup so that you use:
protected override void InitializeViewModelFramework()
{
Mvx.RegisterSingleton<IMvxViewModelLoader>(() => new MvxViewModelLoader>());
}
However, even if this works, then I'd be worried that the linker might be stripping out other symbols in your app - so this might not be enough... you might need to chase this through with Xamarin.