Application.Current.<PageName> returns null - c#

I am developing an app in Xamarin.Forms using MVVM model and I use this method DisplayAlert in PageService class to Display Alerts throughout ViewModels:
public async Task DisplayAlert(string title, string message, string ok = "ok")
{
await Application.Current.MainPage.DisplayAlert(title, message, ok);
}
Everything worked just fine since I reinstalled the application on a testing device and made some minor changes that shouldn't affect MainPage. Now, whenever I call this DisplayAlert method, an exception is thrown:
System.NullReferenceException: 'Object reference not set to an instance of an object.'
Xamarin.Forms.Application.MainPage.get returned null
I really don't know where does the error come from. I googled around and the only thing I found was that there might be some problem in MainPage constructor, but in my case I don't see there any.
So now I am stuck and don't know how to move forward with this problem. Could you please at least point me in some direction on how to find out why MainPage returns null?
Big thanks to anyone responding, I hugely appreciate your suggestions.
Regards,
Honza
Solution:
Cheers, thank you, everyone! I finally managed to solve this issue:
So I have this constructor of App which I edited as Lucas Zhang suggested and also added two breakpoints there:
public static Page RootPage { get; set; }
public App()
{
InitializeComponent();
MainPage = new MainPage(); //Breakpoint 1
App.RootPage = MainPage; //Breakpoint 2
}
I found out, that this code is being executed as following: Debbuger stops at breakpoint 1, then exception is thrown just before the debugger reaches breakpoint 2.
Now, MainPage is actually Tabbed Page that consists of 4 other tabs, and all of these tabs are initialized when "MainPage = new MainPage();" is called. In one of these tabs I use a service. What this service does is basically: Initializes itself and determines whether a user has done something and if not, it displays an Alert that prompts him to do so. And all of that happens just before MainPage finishes its initialization, so of course when calling App.Current.MainPage null is returned.
So, that's it, thank you all once again!

Make sure that you had set the MainPage in constructor of App.
public App()
{
InitializeComponent();
MainPage = new xxxPage();
}
If it still doesn't work , you could firstly use the following workaround .
public static Page RootPage;
public App()
{
InitializeComponent();
MainPage = new MainPage();
App.RootPage = this.MainPage;
}
And reference it
App.RootPage.DisplayAlert(title, message, ok);

Related

How to wait for EventHandler being triggered in UWP app?

I made a simple app in UWP and I'm having trouble with the EventHandlers not being triggered... I made the same app in Core.NET and it works great if I add "Console.ReadLine()" at the end of the main function so it seems like the thread of the main function dies before EventHandlers can be triggered.
Is there a way, in UWP, for the instance to stay alive a while (ie: timeout) to give a chance for the EventHandlers to be triggered.
Note: This is an example of the problem; the real context will happen in the reception of a web request.
Here's the code:
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
test();
}
private async void test() {
Client DiscoverClient;
DiscoverClient = new Client();
DiscoverClient.DeviceHandler += Client_DeviceHandler;
await DiscoverClient.DiscoverAsync();
}
static private void Client_DeviceHandler(object sender, BroadlinkDevice device)
{
int x = 0;
}
}
Instead of using
await DiscoverClient.DiscoverAsync()
you could use
_ = DiscoverClient.DiscoverAsync().Result
This enforces test() to wait for DiscoverAsync() to return.
.Result may only be used if the return type is not void, so you could just let DiscoverAsync() return a boolean when it is finished. The discard is then used to have an assignment that makes the constructor block until DiscoverAsync() is done.
I tried to integrate the library mentioned in your comment into my UWP app, it will throw 'Access Denied' exption when call method GetActiveTcpConnections(line 60 in Network.cs). Since that the event Client_DeviceHandler will not be triggerred. Please see this issue(issue#24369) in github.
This document shows how to use socket in UWP. You may refer the server sample to modify or implement the feature.
https://learn.microsoft.com/en-us/windows/uwp/networking/sockets
I tryed multiple ways found on the internet (some using sockets) but I did'nt find a working solution...
I ended up using a workaround: looping through ip searching for the device's hostname. Since the IP only changes when my router is restarded, the discovery process is rarely needed so even if it's a little on the heavy side, it's quite ok for me :-)
Thanks for you help guys

Calling parent function from frame

I have have a WPF application Im building with the designer. In it I have a Frame that I am loading a Page in.
To be totally honest Im lost. With a lack of instruction and ability to wrap my head around MVVM I am hoping someone might be able to help me understand how to do what I'm trying to do.
From within the page I need to call a public method 'public void UpdateTxt()'. I know this had been done a million time but I just don't understand. Most of my searches pull web/javascript results too.
I did something similar once before with two windows in a winform environment.
public partial class setupApp : Form
{
private Form1 m_parent;
public setupApp(Form1 frml)
{
InitializeComponent();
m_parent = frml;
}
While the above code works in winform enabling me to locate all public functions from the parent window, I can't seem to translate it to WPF.
I have tried
public partial class Childpage: Page
{
private MainWindow m_parent;
public Childpage(MainWindow mw1)
{
InitializeComponent();
m_parent = mw1;
}
This throws no errors on build, but fails to break mode as soon as the debugger launches. I have no idea what the error means as well.
No Matching Constructor Found on type
Why wont the C# back end code translate? Is there a better way?
I think you set the Source property of the Frame in xaml code like this:
<Frame Source="SamplePage.xaml"/>
in this case you need add a parameter-less constructor to your page.
public partial class SamplePage
{
private MainWindow _parentWindow;
public SamplePage()
{
InitializeComponent();
}
public SamplePage(MainWindow parentWindow) : this()
{
_parentWindow = parentWindow;
}
}
But if you want pass the parent window to child page you can set the Frame content in code-behind. like this:
SampleFrame.NavigationService.Navigate(new SamplePage(this));
in this case you don't need to parameter-less constructor.

Xamarin.Forms app crashes because initial page was not created due to loading file

My Xamarin.Forms WP8.1 app keeps crashing because the Initial Page was not created. This is happening because I'm calling an await method before creating the page and the app returns before the page is created.
I need to load some settings from file; which is an async operation. I cannot continue without it. Is there any way to stall the app on splash screen till the settings are loaded?
public App()
{
try
{
InitDatabase();
initAppconstants();
initStyles();
initUI();
SubscribeToMessageCenter();
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
private async void initUI()
{
await ApplySettings();
// code to create pages
}
InitUI() contains the code which creates the start page. The execution returns because of await ApplySettings(); and then crashes as the initial page is not created
See here: https://stackoverflow.com/a/31315711 - as per MSDN article don't use a non-UI thread to load a file... And the app has to be visible before using the API...
Xamarin is crashing your app cause it can't handle it, but that's why it's happening.
I was facing same error. I think I found its root cause and workaround for it.
I noticed that whenever I access ViewModel referrence in my XAML like below, it is not able to resolve referrence of my VM.
<ContentPage.BindingContext>
<xamFormsApp:MainViewModel/>
</ContentPage.BindingContext>
and to achieve above thing when I add reference of my class, it takes "MySampleApp.Droid" assembly referrence like below:
xmlns:myApp="clr-namespace:XamFormsApp;assembly=XamFormsApp.Droid"
But, if I move this binding statement to code behind and remove above assembly referrence like below, it starts working:
public AppMainPage ()
{
InitializeComponent ();
MainViewModel mainViewModel = new MainViewModel();
BindingContext = mainViewModel;
}
In Conclusion, to access code files created in shared project, Forms XAML needs Droid references (Its just my guess, based on what worked and what NOT). Maybe something is broken in XAML compilation.

"Object reference not set to an instance of an object" error in vs13

I am using C# Visual Studio 2013 for Windows, and when I try to debug, this error happens: "Object reference not set to an instance of an object" in:
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
this.Frame.Navigate(typeof(WelcomePage));
}
}
The problem is on the navigation line. How can I fix this?
Constructors are for two things, actually constructing the object (allocating memory and so forth, done for you by the framework) and initializing data, event handlers, and the like. NOTHING else should be done in it, certainly nothing like page navigation.
The Frame object is likely not created at this point, and you shouldn't be using it anyways. Instead, set up an event:
Either:
<Page ...
Loaded="Page_Loaded"/>
or:
public MainPage()
{
this.InitializeComponent();
Loaded += Page_Loaded;
}
Then have a function like so:
private void Page_Loaded (object sender, RoutedEventArgs e)
{
this.Frame.Navigate(typeof(WelcomePage));
}
Besides being much better practice, this will likely solve your exception.
This most likely happens because Frame is still null at the point when you call Navigate I would recommend moving this code else where or adding a nullity check.

Lazy Instantiation of UserControl

I have a WPF application that I am trying to switch the contents of a window efficiently. I have come up with the solution of the following:
App.cs
internal static Lazy<HomeUserControl> HomePage;
MainWindow.cs
public MainWindow()
{
InitializeComponent();
Application.Current.MainWindow.Content = App.HomePage;
}
HomeUserControl.cs
public HomeUserControl()
{
InitializeComponent();
}
I am running into a problem that MainWindow.Content is basically being set to a blank window (it is actually changing the content of MainWindow). If I use App.MainWindow.Content = new HomePageUserControl(), everything works as it should. However, I would like to keep one instance of the page, which is why I made a static one in the App class. This problem occurs whether Lazy<> is used or not. I have tried a check to see if HomePage was null, and I got back a label that said Value is not created., which I'm pretty sure is the representation of an uninitialized Lazy<>; however, this only occurs if I check App.HomePage == null. Any ideas?
Try
Application.Current.MainWindow.Content = App.HomePage.Value;

Categories

Resources