Notify parent page from child page - c#

I am building an app using UWP and I have MainPage.cs which contains a Frame control where I load different child pages. I would like to pass a listener to the child page to notify my parent page about event that happen in the child. On android I would pass a callback listener which I will have to trigger in the sub-pages so I can get notified in parentl The issue here is that pages are started Frame.Navigate(typeOf(LoginPage)) for which I cannot set a callback since login page is not a referece/object but a type class.
Any help would be greatly appreciated.

It seems like the MainPage is a singleton instance. In such case you could just expose this instance by creating a static MainPage Instance property in MainPage and set it in its constructor. Then you could access MainPage directly from any other page.
The proper solution however would be to use a MVVM framework and instead of communicating between the views directly put the communication within the view models. In MVVM you usually have a sort of navigation service which allows passing parameters/return values and also you can have a event aggregator to raise messages to which other components can subscribe. Good examples of MVVM frameworks are MvvmCross, MvvmLight and Prism. It is definitely worth learning to use and integrate them early on, because it will make your life significantly easier in terms of code maintenance in the long run.

Related

Prism event to respond to view being removed from region

I'm using Prism to handle view navigation.
I want a view to respond to it being removed from a region myRegion.Remove(view).
What is the correct way to handle this (in the view)?
Using the Unloaded event doesn't work and neither does OnNavigatedFrom.
One way you can do this is by publishing and subscribing to a CompositePresentationEvent using the EventAggregator. Alternatively, and maybe better, is to implement IActiveAware on your views (it's part of the RegionManager I believe).

Wpf MVVM Load UI control asynchronously

I have a mvvm wpf application that loads up a window consisting of many controls in one go. I want this window to load up the controls separately and asynchronously.
Any suggestions?
For that matter, I use a Singleton pattern. If you're familiar with PRISM and its Bootstrapper, it is kinda similar.
The main idea here is to override the method OnStartup in your App.xaml. Default behavior shows in your xaml StartupUri="MainWindow.xaml", you'll have to remove that property.
In the OnStartup override method, I use a class which creates all my objects (Views, ViewModels, link DataContexts... ) and fires an event when initialization is complete.
At this time I dismiss the splashscreen and show a fully loaded app (the InitializeComponent is called when you create your MainWindow, so it'll be already called at this time).
For more extended use, you can add events in your windows and EventHandlers in your bootstrapper class. I use it for example when I want to fully refresh my app (reboot it), and also for database requests (which are, in my case, performed only on application startup to load the referential).
Hope it helped :)
Unfortunately, if your controls are defined in XAML, they're going to be initialized with the InitializeComponent call and go through the loading process. All of the events in loading a XAML window happen whether or not you subscribe to them.
You could add controls dynamically to the form in code behind, but if you have a separate thread do the work, you would need to use the Application Dispatcher CheckAccess and Invoke methods to ensure the controls are loaded on the thread which owns them.

Creating an MVVM friendly dialog strategy

I'm trying to create a strategy for handling popup forms for use throughout any part of my application. My understanding so far is that I will need a single UserControl in the root of my MainWindow. This will be bound to its own ViewModel which will handle the messages that are sent within the app.
I'm using MVVM Light, and I'm fairly new to the Messenger class.
Imagine a Master/Details scenario, where a list a objects are contained within a ListBox. Selecting one of these items and clicking an Edit button would display a UserControl which covers the whole screen. The user can then edit the selected item, and click OK to commit the change.
I want the UserControl that is opened to be "generic" in a way that I can throw any (probably a ViewModel) at it... for it to render the ViewModel via a DataTemplate and handle all the object changes. Clicking OK will callback to the sending class and persist the change as before.
Some situations where this would be useful are...
Display error messages with no required user input (other than OK to close it)
Display an edit form for a data item
Confirmation dialogs (much like a standard MessageBox)
Can anyone provide any code samples of how I might acheive this?
When designing a UI with MVVM the goal is to separate the concerns of the View from the concerns of the ViewModel. Ideally, the ViewModel should not rely on any view components. However, this is the idal and another rule of MVVM is that you should design your application as you wish.
In the area providing a service showing dialogs there are two different approaches floating arround:
Implementing the DialogService on the View (e.g. see http://geekswithblogs.net/lbugnion/archive/2011/04/13/deep-dive-mvvm-samples-mix11-deepdivemvvm.aspx Sample 03).
Implementing a service component that does is not attached to the view (e.g. see http://blog.roboblob.com/2010/01/19/modal-dialogs-with-mvvm-and-silverlight-4/)
Both approaches rely on an interface that defines the functionality the service provides. The implementation for this Service is then injected into the ViewModel.
Also, do both approaches have their specific advantages and disadvantages.
The first approach works also well for WP7, however, it requires a common view base class as this contains the implementation of the view service.
The second approach works well for SilverLight and WPF and appleals as it keeps the service separate from the view and does not impose any restictions on the view.
Another possible solution is to use messaging to show the dialogs.
Whatever approach you are using try to keep the View and the ViewModel de-coupled by using an IoC (inversion of control) pattern, i.e. define an interface so that you can use different implementations. To bind the services into the ViewModel use injection, i.e. passing the service into the constructor of the ViewModel or by setting a property.
I recently started learning MVVM for a WPF app I was creating, I used this article as a basis for showing dialogs, if you download the sample project then it is actually quite a nice decoupled method, it is nicely abstracted and to get a view you pass an instance of a viewmodel. I extended it somewhat for my own means, I also used the WPFExtendedToolkit MessageBox for warnings, errors etc because the standard win32 MessageBox is fugly.
With regards to dynamic forms then you'll want to investigate the ItemsControl, and in your ViewModels have a Collection of Data Items which need to be edited by the user for the ItemsControl to bind to. I have a dialog for editing actions and their parameters in a workflow system designer where the dialog list of actions was totally dynamic. This was done by exposing a collection of my items with their data types so I could then use a DataTemplateSelector to select DataTemplates which contained the correct types of controls, i.e. a datatype of DateTime showed a DatePicker.
Hope That Helps
From the perspective of a developer coming in to 'maintain' that generic code, it sounds like a pain. From what you've described, I would give the form and the dialog the same view model and create a specific XAML template for the dialog that you want to show.

WPF: Calling method in View from viewModel

I'm using AvalonDock in a WPF application, and need to persist the layout of the AvalonDock the user has setup (moving, docking, detaching of the panels).
The function to do that are on the control itself (SaveLayout, RestoreLayout).
What is the correct way to do that ?
Right now I have a command at the mainWindowViewModel that gets created by the application when creating the instance of the window view and the viewmodel. It basically makes the relay command call an anonymous method that calls the needed function on the view control. This works since the application creates the window and the viewmodel for it.
But how would i approach this if some lower level view and viewmodel had to do this? If using this method I'd have to still create the Command at application level and sending it through the viewModels down to where it is needed to be bound to? Inside it I'd have to search the usercontrol that is a view then the avalonDock control inside it and use that at application level, which is bug prone. Somehow it seems dirty...
Thanks!
You might introduce an interface IView so that the ViewModel can call a method on the View. This way the ViewModel doesn’t need to know about the concrete View class and can still be unit tested.
How this can be accomplished is shown by the sample applications of the WPF Application Framework (WAF).
You can use decoupled messaging to communicate between view models
http://www.bradcunningham.net/2009/11/decoupled-viewmodel-messaging-part-1.html

MVVM Central App Logic

I am using Simple MVVM Toolkit in WPF to create an application, the application uses a central tab control, with a View (UserControl) for each tab item. These Views may also contain tab controls themselves containing further "sub-views".
Our difficulty is in finding a way to share application logic which is used by several of these views, without having one global huge messy class..
I would not go with a huge class which holds everything. But I would have a central ViewModel which controls the overall state. Like the ShellViewModel. And I would let the viewmodels communicate and exchange information via Messenger (MVVM Toolkit light) or EventAggregator (Prism).
They offer way vie Publish/Subscriber Pattern to exchange information. And you can address them by implementing own message classes and pass payload along with it.
So you could have a global Message for Save all and every (Sub-)ViewModel could register to it and runs there own save method after receiving the message...
Prism
http://msdn.microsoft.com/en-us/library/ff921122(v=pandp.20).aspx
MVVM light
http://blog.galasoft.ch/archive/2009/09/27/mvvm-light-toolkit-messenger-v2-beta.aspx
Let me know if this helps...

Categories

Resources