Template10 NavigationService is null - c#

This is my App.xaml.cs
[Bindable]
sealed partial class App : Template10.Common.BootStrapper
{
public App()
{
InitializeComponent();
SplashFactory = (e) => new Views.Splash(e);
var _settings = SettingsService.Instance;
RequestedTheme = _settings.AppTheme;
CacheMaxDuration = _settings.CacheMaxDuration;
ShowShellBackButton = _settings.UseShellBackButton;
}
public override async Task OnInitializeAsync(IActivatedEventArgs args)
{
if (Windows.Foundation.Metadata.ApiInformation.IsTypePresent("Windows.UI.ViewManagement.StatusBar"))
{
var statusBar = StatusBar.GetForCurrentView();
await statusBar.HideAsync();
}
await Task.CompletedTask;
}
public override async Task OnStartAsync(StartKind startKind, IActivatedEventArgs args)
{
NavigationService.Navigate(typeof(Views.MainPage)); // Exception here
await Task.CompletedTask;
}
}
Every time i launch the app i get this exception:
System.NullReferenceException verificata
HResult=-2147467261
Message=Object reference not set to an instance of an object.
NavigationService is always null.
How can I solve this?

I had the same issue when I updated the Target min version of the project to Fall Creators Update (see project properties).
After reading this thread I fixed the issue by updating the Newtonsoft.Json Nuget dependency from version 11.x.x to 10.0.3.
So just to be clear I downgraded the version of the Newtonsoft.Json Nuget dependency.

I have had similar issue, but inside of ViewModel not in App.xaml.cs.
So NavigationService was null when I defined and initialized my ViewModel as property in code behind of view.
Solution is to define ViewModel in xaml (<Page.DataContext>) then everything works like a charm.

For anyone coming back to this, I run across issue and realized that if I kept the minimum version of the project 10586 the problem goes away.

Related

How is Setup class instantiated in MVVMCross in Xamarin?

I'm starting learning MVVM cross, In the android app, I have a splash screen class:
[Activity(MainLauncher = true,
Label = "#string/app_name",
Theme = "#style/Theme.Splash",
NoHistory = true,
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation,
ScreenOrientation = ScreenOrientation.Portrait)]
public class SplashScreen : MvxSplashScreenActivity
{
public SplashScreen() : base(Resource.Layout.SplashScreen)
{
}
}
and this is the Setup class:
public class Setup : MvxAndroidSetup
{
protected Setup(Context applicationContext) : base(applicationContext)
{
}
protected override IMvxApplication CreateApp()
{
return null;
}
}
the problem is that the debugger doesn't hit the constructor of the Setup Class, instead I get "An unhandled exception" after the constructor of the splash screen
EDIT
I've already defined the App class in the PCL project:
public class App : MvxApplication
{
public override void Initialize()
{
base.Initialize();
}
also defined the AppStart:
public class AppStart : MvxNavigatingObject, IMvxAppStart
{
public async void Start(object hint = null)
{
//hardcoded login for this demo
//var userService = Mvx.Resolve<IUserDataService>();
//await userService.Login("gillcleeren", "123456");
ShowViewModel<MainViewModel>();
}
}
The main reason behind this project is to understand the sequence of code required and executed by MVVM Cross, so I provide the minimum code till it runs successfully without runtime errors.
Update
I have read your code again more thoroughly and I can see the issue now. You defined the constructor of the Setup class as protected, which makes it invisible for activation.
On MvvmCross for Android the magic happens inside MvxAndroidSetupSingleton class (see the source code here) which searches for the Setup type you defined. The FindSetupType method looks for your defined Setup class first and then inside the CreateSetup method Activator.CreateInstance is used to build the Setup instance. The CreateInstance method variant used however searches only for public constructors, which means it doesn't find your protected one. The result is that it cannot build the Setup class and crashes.
Original answer
The reason this happens is that you have no Core libary that would define the MvvmCross App class and would initialize other required setup. I suggest you to start with a simple tutorial or to look into the official sample projects to see what is necessary to make MvvmCross work in a Xamarin.Android app.

Xamarin.Forms 2.5.0 and Context

Today I updated to Xamarin.Forms 2.5.0 and saw, that I get the following warnings:
From the Android sub-project:
Warning CS0618 'Forms.Context' is obsolete: 'Context is obsolete as of version 2.5. Please use a local context instead.'
How can I get the local context instead of Forms.Context? Is the Android Context meant?
From the custom renderer:
Warning CS0618 'ButtonRenderer.ButtonRenderer()' is obsolete: 'This constructor is obsolete as of version 2.5. Please use ButtonRenderer(Context) instead.'
In my ButtonRenderer I only have the OnElementChanged() method, so what should I change here? Simply add a ButtonRenderer(Context) constructor? I still get the warning, if I do this in my platform renderer class. Does anyone have an example? The official documentation doesn't mention it and Google also doesn't bring some useful results, except the open source code of ButtonRenderer. This change also concerns many other renderer classes.
Does anyone had experienced other changes, which brakes plugins and so on?
PS: Also I didn't found out, when Device.Windows was deprecated. Now I replaced it with Device.UWP.
I had this same issue for a SearchBarRenderer and all I needed to do to fix it was add a constructor like so:
public ShowSearchBarRenderer(Context context) : base(context)
{
}
Hope that answers the second part of your question.
There are two questions here:
How do I update Custom Renderers to use a local context?
How can I access the current context now that Xamarin.Forms.Forms.Context is obsolete?
How to Update Custom Renderers
Add the overloaded Constructor to each custom renderer
Here is an example using a ButtonRenderer
[assembly: ExportRenderer(typeof(CustomButton), typeof(CustomButtonRenderer))]
namespace MyApp.Droid
{
public class CustomButtonRenderer : ButtonRenderer
{
public CustomButtonRenderer(Context context) : base(context)
{
}
protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
//ToDo: Customize Button
}
}
}
How to Access The Current Context
Install Xamarin.Essentials NugGet Package.
Now, you can call Xamarin.Essentials.Platform.AppContext when you need to access the current activity.
Here's an example of how to open the App's Settings in Xamarin.Forms.
[assembly: Dependency(typeof(DeepLinks_Android))]
namespace MyApp.Droid
{
public class DeepLinks_Android : IDeepLinks
{
Context CurrentContext => Xamarin.Essentials.Platform.AppContext;
public Task OpenSettings()
{
var myAppSettingsIntent = new Intent(Settings.ActionApplicationDetailsSettings, Android.Net.Uri.Parse("package:" + CurrentContext.PackageName));
myAppSettingsIntent.AddCategory(Intent.CategoryDefault);
return Task.Run(() =>
{
try
{
CurrentContext.StartActivity(myAppSettingsIntent);
}
catch (Exception)
{
Toast.MakeText(CurrentContext.ApplicationContext, "Unable to open Settings", ToastLength.Short);
}
});
}
}
}
use Android.App.Application.Context
There is a discussion of this topic on the Forums

Error when opening solution in second computer

I have a Visual Studio project in Dropbox, I have been working on this project from two different computers (NOT at the same time) but for some reason, it just stopped working on one computer, I can open it in one but when I try to open it from the other computer I see an error.
FYI - One computer is running Windows 7 and the Other one is running Windows 10 but both are running Visual Studio 2015. Also, I'm using MVVM Light in this solution.
Error:
TypeInitializationException was unhandled by user code
An exception of type 'System.TypeInitializationException' occurred in MyApp.exe but was not handled in user code
Additional information: The type initializer for 'MyApp.ViewModel.MainViewModel' threw an exception.
I tried cleaning the solution but nothing, no luck.
Any idea why it would stop working on one computer but not the other if it's the same solution?
EDIT: Added code.
namespace MyApp.ViewModel
{
public class ViewModelLocator
{
private static MainViewModel _main;
public ViewModelLocator()
{
_main = new MainViewModel();
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
"CA1822:MarkMembersAsStatic",
Justification = "This non-static member is needed for data binding purposes.")]
public MainViewModel Main
{
get
{
return _main;
}
}
public static void Cleanup()
{
}
}
}
Constructor fo MainViewModel
public MainViewModel()
{
CurrentViewModel = MainViewModel._findrViewModel;
FindrViewCommand = new RelayCommand(() => ExecuteFindrViewCommand());
CalculatorViewCommand = new RelayCommand(() => ExecuteCalculatorViewCommand());
ProductionTimesViewCommand = new RelayCommand(() => ExecuteProductionTimesViewCommand());
}

ASP.net identity: How to get current IdentityUser (ApplicationUser)? Where is UserManager.FindById?

I started with the default template for ASP.net in VS2013. I want to get the current user object. This should be possible without directly accessing the database.
In the documentation, this looks very easy: http://blogs.msdn.com/b/webdev/archive/2013/10/16/customizing-profile-information-in-asp-net-identity-in-vs-2013-templates.aspx
So it should be
var currentUser = manager.FindById(User.Identity.GetUserId());
But FindById is missing! Since several hours, I have been trying to use FindByIdAsync instead. But I think I get a dead lock.
public class UserManager : UserManager<IdentityUser>
{
public UserManager()
: base(new UserStore<IdentityUser>(new ApplicationDbContext()))
{
}
public async System.Threading.Tasks.Task<IdentityUser> GetCurrentUser()
{
var user = await FindByIdAsync(HttpContext.Current.User.Identity.Name);
return user;
}
}
The calling propery:
private IdentityUser_CurrentUser;
protected IdentityUser CurrentUser
{
get
{
if (_CurrentUser == null)
{
var manager = new UserManager();
var result = manager.GetCurrentUser();
//-- STOPS HERE!!
_CurrentUser = result.Result;
}
return _CurrentUser;
}
}
Any help would be appreciated! Either to show me where FindById is gone or how to make my code work. Or is there another way to load the IdentityUser?
ADDED
In the user manager, FindById is not found, but this.FindById is found. I will add the screenshots. This is not a proper solution because I do not understand, why this is happening, or can someone explain this behaviour? I attach 2 screens with intellisense open. I also want to mention, that it is not a problem of intellisense - the code does not compile if I do not add this.
Intellisense entering "Fi":
.
Intellisense entering "this.Fi":
This way, at least I am not stuck any more.
FindById is an extension method coming from Microsoft.AspNet.Identity.UserManagerExtensions class. It is a part of Microsoft.AspNet.Identity.Core nuget package.
You should add
using Microsoft.AspNet.Identity;
to your code to start using non-async methods.

WinRT 8.1 settings in Caliburn.Micro

I'm trying to open a settings view in a Caliburn.Micro WinRT 8.1 app using VS2013 RC, but I keep getting an unhandled exception when opening it with the following message:
Value cannot be null. Parameter name: Could not parse the VisualElements from the app manifest.
I can reproduce the issues with the following steps:
create a new Windows Store app from VS2013 RC using the Blank app template.
add Caliburn.Micro via NuGet.
in App.xaml, change the base class to caliburn:CaliburnApplication (the namespace is declared as xmlns:caliburn="using:Caliburn.Micro").
in App.xaml.cs, change the class like this (for the CM-based settings I follow http://compiledexperience.com/blog/posts/settings-caliburn)
Code below:
public sealed partial class App
{
private WinRTContainer _container;
public App()
{
InitializeComponent();
}
protected override void Configure()
{
_container = new WinRTContainer();
_container.RegisterWinRTServices();
_container.PerRequest<MainViewModel>();
_container.PerRequest<SettingsViewModel>();
ISettingsService settings = _container.RegisterSettingsService();
settings.RegisterCommand<SettingsViewModel>("Test settings");
}
protected override object GetInstance(Type service, string key)
{
var instance = _container.GetInstance(service, key);
if (instance != null) return instance;
throw new Exception("Could not locate any instances.");
}
protected override IEnumerable<object> GetAllInstances(Type service)
{
return _container.GetAllInstances(service);
}
protected override void BuildUp(object instance)
{
_container.BuildUp(instance);
}
protected override void PrepareViewFirst(Frame rootFrame)
{
_container.RegisterNavigationService(rootFrame);
}
protected override void OnLaunched(LaunchActivatedEventArgs args)
{
DisplayRootView<MainView>();
}
}
Finally, create folders for Views and ViewModels in the solution add add to them the required items: MainViewModel, SettingsViewModel, MainView, SettingsView. The views just include a TextBlock with some text. MainViewModel derives from Screen, while SettingsViewModel derives from PropertyChangedBase. There is no relevant code in any of them.
When launching the app, I can see the main view; then I open the charms bar and click settings, and I find the label leading to my app settings; when I click it, I get the exception quoted above. Any hint?
You can find a full repro solution here: http://sdrv.ms/18GIMvB .
If you aren't ready to move to the alpha version of CM, you can update Callisto to 1.4.0 via NuGet. That fixed the error for me.
It seems that the new CM release (alpha 2) fixed the issue, so I'm adding some more information here to help other newcomers like me. Here is what I'm doing now:
In app's Configure I have some bootstrap code like:
...
ResourceLoader loader = ResourceLoader.GetForViewIndependentUse("Resources");
ISettingsService settings = _container.RegisterSettingsService();
settings.RegisterFlyoutCommand<ContentSettingsViewModel>(loader.GetString("SettingsContent"));
The ContentSettingsViewModel is a viewmodel for filtering some contents. The string got from resources is the label which will appear in the settings flyout (be sure there is an entry for this string, as passing an empty or null string triggers an exception). This VM is derived from CM Screen as I'm overriding OnActivate and OnDeactivate to load and save settings when the user opens or dismisses the settings page.

Categories

Resources