In WPF, you can get global mouse events by registering in App.xaml.cs as below.
EventManager.RegisterClassHandler(typeof(Window), Window.PreviewMouseDownEvent, new MouseButtonEventHandler(OnPreviewMouseDown));
EventManager.RegisterClassHandler(typeof(Window), Window.PreviewMouseUpEvent, new MouseButtonEventHandler(OnPreviewMouseUp));
EventManager.RegisterClassHandler(typeof(Window), Window.PreviewKeyDownEvent, new KeyEventHandler(OnKeyDownEvent));
In UWP, I wonder how I can get a PointerMoved event from App.xaml.cs in my application.
You can access the main window content with the singleton class provided:
Window.Current.Content.PointerPressed += OnPointerPressed;
Window.Current.Content.Pointer... // etc...
Related
How bad idea is to create application only once and use it all time when calling OnCreate in Android app:
protected override void OnCreate(Bundle bundle)
{
...
if(FirstRun)
_app = new App(new AndroidInitializer());
LoadApplication(_app);
}
The application resumes much faster. I did not noticed any issues during basic tests. FirstRun and _app are static properties.
OnCreate is called again for new activity when previous activity was destroyed. It happens for example when exiting app with back button or changing theme to dark.
First of all, a Xamarin Forms Application doesn't have an OnCreate method. An Android Activity has.
The activity's OnCreate is only called when FirstRun is true - when the activity's reused, the system calls OnRestart and OnStart, as described in the docs. If the activity get's destroyed, the FirstRun flag won't survive.
The application I'm currently working on requires data to be retrieved from a web service during app startup that roughly takes 1.5 seconds. After the data is retrieved, it needs to be displayed on the MainPage and that is another 1.5 - 2 seconds since the data is mostly URLs of images that have to be displayed, in my case, using ffimageloading library; which means actually downloading those images first to be displayed.
I have splash startup screens for both Android and iOS implemented separately in platform projects but splash screen only stays up for the amount of time Xamarin Forms needs to load and afterwards disappears not waiting for my actual model to load from the web service. I have searched for solutions to extend the splash screen duration and mostly every solution I have read involves creating another splash screen page, loading page if you will, that is already controlled in PCL project but having two separate splash loading screens just seams not feasible to me at the moment.
So I was wondering, how would one load the initial model in platform projects, during the actual splash screen, and then later pass it to PCL project when Xamarin Forms has finished initialization, presumably to App.xaml.cs 's App() constructor function?
There is no code or enough details so I am assuming this is what you want to do.
Call the APIs asynchrnously , till then show splash screen.
Before assigning MainPage in your App.xaml.cs you should call these APIs asynchronously with await and then you use the same for binding of your mainpage
public App()
{
InitializeComponent();
//do all my prefetch stuff for app initialization.
// API and what not
var viewmodel = new AppMainViewModel();
await viewmodel.CallFooFetchAsync();
await viewmodel.BlahBlahAsync();
MainPage = new NavigationPage(new AppMainPage(viewmodel));
}
In Page
public AppMainPage(AppMainViewModel vm)
{
BindingContext =vm;
}
So by the time page loads it has all the data handy.
You can explore adding this code in OnAppearing of the page.
Note that the concept of default Splash screen is just to show an image(with different theme in Android) and setting image in iOS. You need to have conventional UI technically its not splash screen anymore.
Alternatively you can get shared project handle in native
Android Sp
protected override void OnCreate(Bundle bundle)
{
...
var app = new App(); //this will be shared project App object
Device.BeginInvokeOnMainThread(async () => await app.DoPrefetchStuffFirst()); //API calls if needed in this async method
//then
LoadApplicationm(app)
}
You can do similar thing in iOS AppDelegate
And if you call native specific methods in platforms (may be for API calls) then you would use DependencyService feature , that will pass it to shared project or Custom renderer based on where you want to use it.
The application I am working with uses AppCenter with code like this:
public App()
{
InitializeComponent();
VersionTracking.Track();
VersionChecks();
VersionChecks();
DB.CreateTables();
DB.GetSettings();
DB.PopulateTables();
SetDeviceInfo();
SetResourceColors();
SetResourceDimensions();
MainPage = new AppShell();
}
protected override void OnStart()
{
AppCenter.Start("xx", typeof(Crashes), typeof(Push));
Analytics.TrackEvent(VersionTracking.CurrentVersion);
}
Although I don't see any error messages when it starts up I am concerned about the way this is coded as from what I can see the App constructor fires first followed by the OnStart().
So if this happens, how can VersionTracking work. Should that code not be in the OnStart and how about the additional code that I have which sets up the application?
Would appreciate any advice that people can offer about the use of AppCenter with Xamarin forms.
Answer
Yes, you can use Xamarin.Essentials.VersionTracking in the constructor of App.
Explanation
You are confusing three different SDKs: Xamarin.Essentials, Xamarin.Forms and AppCenter.
VersionTracking is an API in Xamarin.Essentials.
App is a subclass of the Xamarin.Forms.Application API.
AppCenter.Start is an API in the AppCenter
These are three independent SDKs and each can be used independently of the others.
Xamarin.Forms app startup flow is like : Native App Startup -> Xamarin.Forms.Application Startup
Your App class is instantiated only after Native app has finished loading.
As versioning is managed by native app, there is no problem in initialising VersionTracking in constructor, as Native app has fully loaded by this time.
I'm running into an issue on android where our TimePicker and DatePicker stay visible when we navigate OnPause(). We need to redirect our users back to the login screen when they background the application, but if the TimePicker or DatePicker is active when they do this it stays on the screen. It appears above the login screen and pressing cancel or ok crashes the app.
We are hooking into the native android lifecycle events (not just using Xamarins built in hooks) and we redirect OnResume(). I've tested this in a barebones app though and it still happens OnPause().
Here is our TimePicker causing us the issue:
<TimePicker x:Name="VitalTimePicker" HorizontalOptions="Fill" VerticalOptions="Fill" IsVisible="false" PropertyChanged="OnTimePickerPropertyChanged"/>
And here is an example of changing screens on a lifecycle event:
protected override void OnSleep()
{
App.Current.MainPage = new NavigationPage(new NotesPage());
}
Any ideas? I was thinking of clearing the Pickers but I can't seem to find how to do that
Edit
Just to add a little more context
The Application class (app.xaml.cs) has lifecycle hooks that we use to catch when our users background the app. In here we call MainPage = new NavigationPage(new LoginPage()); which takes the app back to the login page.
I've added
protected override void OnDisappearing()
{
VitalTimePicker.Unfocus();
VitalDatePicker.Unfocus();
}
to the view i'm working from and it seems to be called when we background the application, but for some reason the TimePicker is staying on the screen when our login page pops up again.
You can programmatically close DatePickers and TimePickers using the method Unfocus(). I'd recommend closing them before you call the next page, as I don't know if they will be able to be referenced and closed after the other screen has been initialized.
Create a method that calls VitalTimePicker.Unfocus() and the same for any other picker you have, and call this method before changing to login screen and you should be good to go.
I'm currently working on a Xamarin.forms project using .NET Standard as code sharing strategy. I try to use the MVVM pattern by using the MvvmLightLibsStd10 library. I already successfully setup the MVVM structure by using this tutorial:
https://www.linkedin.com/pulse/build-xamarinforms-net-standard-mvvm-light-app-rafael-carvalho
I can't use Navigation.PushAsync(new Page()); because it only works in code behind and not in the ViewModel.
I already tried to Pass Navigation trough the VM constructor, like describe over here:
Xamarin.form Page Navigation in mvvm
But when I try this method, an error occurred at "LoadApplication(new DemoMVVM2.App());" in MainPage.
How can I switch pages using MVVM Xamarin.Forms with MVVMLight (based on the code from my first url)?
but I have no Idea how I can switch Pages via the ViewModel and keeping the header with back button.
Generally when working with MVVMLight you'll be using a NavigationService.
This class can be constructor injected in your VM, thanks to the build in IOC in MVVMLight.
With it you can do Navigate and GoBack in your VM, triggering a real navigation on the current stack.
Only thing that you maybe missed, is the fact that you need to write one yourself for Xamarin forms.
But Laurent Bugnion ( the owner of MVVMLight ) supplied an example available here:
https://github.com/lbugnion/sample-2016-vslive-crossplatform/blob/master/Flowers/Flowers.Forms/Flowers.Forms/Helpers/NavigationService.cs
You can pass a callback to your ViewModel(VM) and on Command or whatever action call your navigation code which is in your page (View). this way you can keep your navigation code in your page and your binding logic in your ViewModel.
interface NavHandler{
void navigateToSomeView();
}
public class MyPage : ContentPage,NavHandler{
public MyPage(){
BindingContext = new MyViewModel(this);
}
void navigateToSomeView(){
Navigation.PushAsync(new Page2());
}
}
public class MyViewModel{
NavHandler handler;
public MyViewModel(NavHandler handler){
this.handler = handler
}
//Your action
this.btnClicked = new Command(async()=>{
handler.navigateToSomeView()
}
}