Global MVVM ViewModel in UWP app - c#

In WP8.1 or WPF desktop apps I could create my ViewModel as a static instance in App.xaml.cs and refer to it throughout the app as "App.myViewModel" but in UWP that does not seem to work (perhaps by design?).
The reason I want a global ViewModel is that, like many apps, I have one main page that populates the VM by downloading info from websites (I'm working on a business based RSS Reader for a client) and when I navigate to another page then come back to MainPage my vm is empty again (as I appear to have no option but to declare it in MainPage) so I have to reload all the data every time.
Also if I want to access the VM from navigated pages I now have to pass a reference to the VM through to that page whereas with the global approach I could still access App.myViewModel.
The only time I alter the VM contents is from UI actions on the Mainpage so I just want to be able to navigate back to the main page from other pages and have the VM still intact.
Can someone please explain how this is done in UWP? Can I still use App.xaml.cs and if so, how? If this is not possible why was it designed like this?

You are looking for ViewModelLocator. Here you have nice explanation and example how to use it. https://stackoverflow.com/a/14154088/4727426

Related

Open gallery in simulator on image tap

I want to open the gallery in iPhone simulator upon button click.
I am using Xamarin forms - xaml to create pages and image views.
What I have implemented so far :
I have a GalleryService specific to iOS that implements IGalleryService that has a method selectImage. The selectImage creates a UIImagePickerController _imagePicker.
In iOS specific apps, I would just do
NavigationController.PresentModalViewController(_imagePicker, true);
But how to do something similar using Navigation in xamarin forms?
PS: I have created view in .xaml file and move across pages in xaml.cs file like
Navigation.PushModalAsync(page)
Here, the page must basically contain the _imagePicker view, right? How to do that?
Kindly correct me if I am wrong.
Xamarin.Forms actually utilises a single NavigationController on iOS to host all the different pages. All of the Xamarin Content Pages navigation happens internally in XF, inside the single main NavigationController.
You cannot mix other native view controllers inside the NavigationPage stack. But you can use all the native code you normally would and just treat the one NavigationController that forms uses as a single "screen".
Inside the iOS native project, you can use
var topController = UIApplication.SharedApplication.KeyWindow.RootViewController;
while (topController.PresentedViewController != null) {
topController = topController.PresentedViewController;
}
topController.PresentViewController (_imagePicker, true, null);
to access the XF's view controller, find the top one and use that like you would in a "native" ios app to present the modal view.
Note that this RootViewController will be null until "LoadApplication" finishes, so make sure any calls are made after that, which should always be the case if you are triggering this action from the running app and not immediately on startup.
If using PCL's, you would need some form of a DependencyService to trigger this call from your shared code, and you might need a bit more logic in the native app to get the result back into the shared code. You would also need to reimplement this on any other platforms you might be targeting with your app (such as Android or UWP).

Lost DataContext when navigating back in Frame (SplitView) in UWP

I'm writing an Universal App in C# for Windows 10 using the SplitView with a frame for navigation.
I have a sidebar with a list that I load dynamically and, when I click on one of the items, I navigate to a page using the model from the menu to indicate which item I should load in the Frame.
I followed this sample: Windows-universal-samples/Samples/XamlNavigation/
The only difference is, instead of having multiple pages, I have only one page that is loaded every time I select a different item with its specific ViewModel. I use Autofac to load the ViewModels and MyFrame.Navigate(typeof(DetailsPage), idOfItem);to load the page.
The problem is, every time I navigate to the next page, it seems that the instance of the previous one is lost and when I navigate back, it loads a new instance. This kind of thing doesn't seem to happen when I'm navigating in the RootFrame and it didn't happen in Windows Phone 8.1.
I've been searching for a solution on the Web for hours, but I can't find anything relevant.
Does anyone know why this could be happening?
I hope I was clear enough with my question.
Thank you in advance for the answer.
The behavior you observe is correct and as expected. You have two options:
You can use Page.NavigationCacheMode, set it to Required. This is easy, but may consume a lot of memory.
Or you can save page state in OnNavigatedFrom and restore it in OnNavigatedTo. In fact, depending on your scenario, it may not even be necessary to save state in OnNavigatedFrom, assuming the state (your DataContext) can be constructed when returning to the page in the same way that you constructed it when first comming to the page.

Create Single Window Navigation in WPF

I want to create a kiosk mode application using WPF. I want to use a single window because the user should not be able to exit this fullscreen application.
The application should guide the user trough a process. When the user proceeds trough the process, the screen should constantly change and show him the next step.
Usually I just create a single window and use a "state machine" to switch UserControls containing the information for the current step. Is there a better way to achieve this functionality? Maybe I would get a better result using multiple windows or Pages (never used them).
The reason why I am asking is that in future I want to have a simple, clean way of switching the content inside a single window. i.e. I am planning to implement some sort of animation when switching content (like sliding to the next / previous step). I don't want to put more effort into my current approach if it isn't the most flexible and clean one.
Any ideas?
PS: This is about desktop applications. Today I come from the Winforms environment and am experimenting with WPF.
There's a few ways you can achieve this.
First would be to use a Page based application, this will allow you to use a single window. Here is a pretty interesting tutorial
A bonus of using this approach is that navigation between pages is built in.
Your requirements are that you need to use animation for transitioning between pages, as far as I'm aware, using a Page based application cannot achieve this (I may be wrong). So your other option would be to use a UserControl MVVM approach.
This probably won't make a lot of sense now, but here goes:
You can use a single master view model which will hold multiple child view models, each of these could have a visibility property which dictates the visibility of the associated view. The master view model would simply be responsible for displaying the appropriate view model depending on where the user currently is in the application.
Using some clever XAML, you can create storyboards (animations) when the view becomes visible, which will allow you to achieve the crazy awesome animations that you require.
Anyway, that probably didn't make any sense, so here's a tutorial to get you started with MVVM.

How to create tabbed page in Xamarin.Forms similar to that of Facebook app

I am working with Xamarin.Forms and I would like to create a navigation method similar to that of the Facebook app and also other newer versions of different apps. Here are two pictures, one of Facebook app on Android and the other is of KakaoTalk, also on Android.
I've tried several different ways to implement this. For example I wrapped the MainPage (TabbedPage) inside a NavigationPage. I also tried wrapping the MainPage (ContentPage) inside a NavigationPage then calling
PushAsync(new TabbedPage());
inside the MainPage via the Navigation property. I also tried wrapping the children of the MainPage (TabbedPage) inside separate NavigationPages. None of these attempts resulted in the desired effect.
I would like the following to happen. When a user taps on a Button or something that navigates to another page I'd like a ContentPage to pop in front of everything (tab bar included) except for the Navigation bar (or Action Bar). Obviously this happens via the PushAsync() method which also results in a small back arrow appearing in the Nav bar. My understanding is that a PushAsync() call pushes the chosen page onto the navigation stack provided by the NavigationPage. Therefore if a TabbedPage is wrapped inside a NavigationPage a new ContentPage would not be able to pop in front of the tabs like in the two applications mentioned above.
This, plus the fact that the tab bars of said apps don't get inside the ActionBar (in Android) in landscape mode leads me to believe that what I'm trying to achieve is best done not using TabbedPage but something that acts like a tab bar, e.g. a horizontal stack of Buttons perhaps.
Has anyone implemented this correctly and in an elegant way using Xamarin.Forms? So again, I would like to make this tab like navigation with the tabs staying underneath the ActionBar in landscape mode and a new Page appearing in front of the tabs (hiding them) when pushed onto the navigation stack. Do you think this can be done with Custom Renderers? Of course in iOS these are done with tabs but in Android I'm not sure.
What I would like is not necessarily code examples, but a best practice on this issue. So again, this is in Xamarin.Forms with a common PCL project and an Android and iOS project. Thank you in advance for your answers and advices!
P.S.: I've obviously searched this site before (Google as well) but I've found no real articles on this issue.
I have used ToolbarItems order=primary for navigation bar menu button and ToolbarItems order=secondary for tab bar on top.I have PCL the code written is in XAML. :)
http://codeworks.it/blog/?p=232
My understanding is that a PushAsync() call pushes the chosen page onto the navigation stack provided by the NavigationPage. Therefore if a TabbedPage is wrapped inside a NavigationPage a new ContentPage would not be able to pop in front of the tabs like in the two applications mentioned above.
This is not true actually. According to Xamarin API Doc, the Navigation property is context-aware, i.e. it will find all its parents until there is a NavigationPage.
In Android, only one NavigationPage is allowed and therefore even you call PushAsync() inside the TabbedPage, it will still push via your wrapping NavigationPage.
You can create a custom controller using the grid. it will remove the hassle of writing custom renderers.

Sharing the same viewmodel between pages/main page and sub-page

I'm kinda new to the whole windows platform and I'm trying to create mvvm portable class library for windows and windows phone. Now that I have all my smaller pieces ready, I've found myself stuck at trying to figure out how to achieve the following with mvvm.
I have a main page where I can see the information for a car rental reservation and in this page. I'll be able to see a pickup location and a dropoff location (which are both inside a PointOfInterestViewModel). When I click on either the pickup/dropoff location. I want to switch to anther page which has a pivot with multiple list of possible locations. Once the user selects a location, I'll want to update the location in the PointOfInterestViewModel and then send the user back to the main view.
Is there a way where I can achieve it without having multiple PointOfInterestViewModel(s) and passing data between them? I would much rather have one single viewmodel but still adhere to mvvm.
You could put the PointOfInterestViewModel on the App class, bind the main form to it - then you could update it from the pivot:
((App)App.Current).PointOfInterestVM = ....

Categories