Detecting application exiting and how to stop when changes are not saved - wpf

Using the Composite Application Guidance tools from Microsoft, It seems as if there is no mechanism to allow you to query your modules ViewModels and ask if any of them have unsaved data. This is a problem because, and I'm guilty of this as well, you cannot stop the application from terminating when there is unsaved data...
I had thought about creating an interface called IApplicationEvents and have an event on there called ApplicationExiting. The thought being that each module can subscribe to the event and, when fired, can send back a "Cancel=true" or "Cancel=false" to say whether or not to allow the application exiting.
Curious to find out what others may have done in this instance, and to see what possible solutions there are in the community to solve this issue.
Thx.

There are a lot of choices here.
First off, I wanted to clarify a little nomenclature... typically your Views or ViewModels contained within your Module assemblies are the things with unsaved changes, not the Module itself. The Module is responsible for instantiating any views necessary at the start and contributing back to the shell during Initialize and that's typically it, so when you attack this problem, you'll want to focus on your views/viewmodels and not the Module classes.
Options off the top of my head:
Adopt a complimentary framework like Caliburn that has support for application events like this (as well as some MDI events like ViewClosing, that kind of thing). It has builtin support for Prism (http://caliburn.codeplex.com/)
Use a composite command. Your views or viewmodels will register themselves with a composite command elsewhere (CloseCommand, which you declare statically for your application) and every open view will have its CanExecute and Execute methods fired so that you can both vote in the closing of the application and also react to it, should it happen anyway. CompositeCommands are a feature of Prism. (See: Commanding Quickstart)
I think those are probably the most elegant. There's a few more options but these live in the best harmony with existing conventions.
Hope this helps.

Related

MVVM navigation how to

I dont hope to get any answer but i will try to be clear.
I tried Caliburn Micro . At first it seemed fine and all i need. Some features yes but other not.
All i wanted is a single window with some views as usercontrols and multiple dialogs at each view. Using a conductor.OneActive i could achieve the first with little pain. However switching between views even looking the example was to cast Parent to Conductor and call a method there.
Even example of caliburn micro did casting like this. Calling .close(false) at screen was same as close(true) resulting in killing the view and recreating causing lag in lowest end atom pc.
So only solution was to cast to parent.
Dialogs
I tried tons of dialogs examples but non worked and made my life hard.
Messagebox etc were DEAD easy but in case you wanted multiple dialogs you were out of luck.
If you put code at close callback to open another dialog you got bonus stackoverflow exception as it gets confused.(Endless loop).
I could figure a good dialog that could cache the view and at the same time to display efficiently multiple dialogs.
Event Aggregrator
Also i cant figure out how on earth event aggregrator is suitable for switching views. In case you have multiple conductors it could be a hell to manage.
To show a dialog - as in Modal Dialog that blocks the view that showed it - you should be using IWindowManager.ShowDialog.
You should take a look at prism library http://compositewpf.codeplex.com/
see navigation chapter: http://msdn.microsoft.com/en-us/library/gg430861%28v=pandp.40%29.aspx
But I don't know how EventAggregator could help you to switch views… you could subscribe to received an event on a closingView but… …
You might want to take a look at Catel. It has a UIVisualizerService which allows you to show windows based on their view model.
It also has a ViewManager (IViewManager) which allows you to manage all views inside your whole application. Besides that, it also provides a ViewModelManager (IViewModelManager) which does the same for your view models. Best of all: you can find all views that are connected to a specific view model in your application to interact with that.

Protecting against exceptions thrown by child controls in WinForms

I am writing a WinForms based IDE-style application. As part of that application it loads plugins which implement an interface called IFeature. Features are loaded by the main IDE framework via MEF, and then asked to instantiate an instance of Control, which is then added to a tab page to form the main working surface for the plugin. So far so good.
I'm now working on trying to protect the IDE from badly implemented plugins, and I am out of good ideas on how to do that, exactly. If, for example, a plugin is a button which throws an exception, then the IDE framework code is not involved in that call-stack at all, so there is no place for me to inject a try-catch. I have hooked onto the AppDomain.CurrentDomain.UnhandledException and Application.ThreadException events, which provide a top-level protection against exceptions thrown in that manner, but I was hoping to be able to catch them with some context so that the exception could be tied to the IFeature instance that was responsible for the problem.
I did have the idea of creating a class derived from Control - and then over-riding all sorts of methods and implementing try-catch - but that
a. Seems clumsy.
b. Wouldn't protect against controls which in turn over-ride the method.
c. Would prevent any non-custom controls as being used (for example, Panel)
Are there any other methods I can use to provide closer-to-the-cause protection for my framework, or am I stuck with the handling the very broad scope events as above.
Thanks
Matt
In general I would not burden myself too much with this.
Just tell the plug-in developers that when you catch an exception that their control let slip you will remove all references to the control.
It is too hard to do anything else because you will have to envision everything a control could do wrong.
For a non-UI plugin I would kill the appdomain.
Removing all references might not be as safe and that's probably why many programs that allow UI plugins do not allow the UI to be drawn by the plugin but instead draw the UI for the plugin based on what the plugin suggests through an interface.

Where to put code in (primarily) windowless WPF app?

So I'm planning on writing an application that is largely a windowless application. There will be windows for user interaction, but only at the request of the user. Otherwise the application sits in the system tray and runs a timer, executing some logic every minute or so. My question is this: As far as I can tell, I would put all the related logic in App.xaml.cs (starting the timer, executing the logic at each interval), but for some reason this seems wrong to me.
The app will have a system tray icon that users can interact with to get details, adjust settings, etc., but otherwise the app just sits there and does what it does. Is it appropriate to put all the code in the code-behind for the App.xaml class? I don't know why, but it seems as if I shouldn't, and there should be somewhere else, but I can't really think of anything.
I've never written an app like this before, hence my ignorance. Any advice would be greatly appreciated. Thanks.
James
Even with applications where most interaction is done through windows it's usually a bad idea to put all the code in the code behind. Interactions are often initiated eventhandlers in the code behind but you can put your code in classes you create yourself.
The same goes for applications that do not show a user interface most of the time. Most of the actions will be initiated from the App.xaml.cs but that doesn't mean all the code has to live there. You can encapsulate timers in their own classes that can kick off other code to do work for example. Divide your code up along lines of responsibilities, a window class does UI stuff, domain logic goes into other files etc. That will enable you to create more maintainable applications.
It doesn't sound like the code belongs there, and at most just a call to start the timers.
What does sound like a perfect fit for your issues, is the M-V-VM (Model - View - ViewModel) pattern. As you noteded, it also will 'feel' more correct then attaching logic to your code behind. Using MVVM you can separate your sparse UI into a View, and your code can exist separately in the Model and ViewModel.
I would recomend using the toolkit here, as it also contains good overview documents and a sample you can digest as you create your own solution. Laurent Bugnion has also released a MVVM starter toolkit that you could use to get started.
Also, here is some good stuff to get you started on actually setting up your controls in the system tray.

WPF - PageFunctions. Why are they needed?

I've been dabbling in WPF for a couple of months now and I've managed to grasp most of what's about and why/when it's used but I'm still struggling to see the value of the PageFunction class.
Can someone give me a simple, but concrete example of when a PageFunction might be the correct tool for the job?
Mainly, it seems to be a pattern to formalize branching in task based UI.
Let's say you have a form with a checkmark for an optional feature, but this feature requires additional information which is too complicated to fit on the same page.
Using this pattern allows delegating information collection to another component.
Moreover, there is kind of a strategy pattern applied, since you could have various subsystems able to collect the same information, all of them inheriting the PageFunction(of T), so that the code actually calling those does not need to know any detail about it.
Those are just some ideas, I have not exactly looked into it.
PageFunction in a page = Dialog box in desktop application (without Page).
You can use a PageFunction every time you use a dialog box in a desktop application and that you want to develop a webnavigation-like behavior to your program.
The main thing page functions enable is implementing workflows with sub-tasks and managing the return stack.
If you just rely on page-to-page navigation, it's hard to pause the current navigation path, do something else, and then come back and continue. PageFunctions enable that through the concept of Returning and unwinding the navigation stack.
I provided some real world examples of this here: http://www.paulstovell.com/wpf-navigation

Silverlight RoutedEvents and Exceptions

I have a complex application that consists of an Application, containing many modules, each containing many views. The behaviours of my views may throw exceptions.
Sometimes I want to handle exceptions on the view that created them, sometimes in the parent module, sometimes in the grand-parent application.
The concept of RoutedEvents seems like a sensible way of approaching this problem, but I'm not entirely sure how to go about that.
Does anyone have any examples or links they can share that demonstrate what I am trying to acheive?
Thanks
Mark
Although Silverlight contains the RoutedEventHandler and RoutedEventArgs, unfortunately the concept of "routed events" as seen in the desktop WPF framework is not the same.
Today it's kept for source and API compatibility, and in the future, maybe it could be supported.
What this means is that, in the meantime, you may be able to do a little extra work and still accomplish this by
at the Application level, hooking up your own unhandled exception handler code, perhaps create and name the type "AdvancedExceptionManager" or whatever, and design a simple API on top of that to allow things to subscribe and process any exceptions and bubble it up.
at the module level, working with the global/Singleton unhandled exception handler code, subscribe and unsubscribe to "handling" the global exceptions, and canceling further processing, for instance.
Let me know if you need more information on how to go about this. It would help to know how your "modules" are constructed or designed.
This might be interesting for you:
"RoutedEvents implementation for Silverlight 3 including WPF compatibility"
http://sl3routedevents.codeplex.com/

Resources