Adding UnhandledException support to a ViewModel - wpf

OK - so I have a legacy MC++ app that calls WPF views like they are dialogs. I have an abstract ViewModel parent class. Is there a way that I can add UnhandledException handling to my ViewModel so that any exceptions thrown within the ViewModel or it's child implementations can be handled there before propagating out to the MC++ app?
I don't really have an architectural framework to work with. All the ViewModels and Views implemented to this point have been one-offs :(

You should be able to add exception handling to the method that opens and shows the View as a dialog (ie: wrap the Window.ShowDialog() call). This should catch any exceptions thrown from within your View or ViewModel, as they're all "launched" from that point.

If you have access to a Dispatcher, you can tie into the Dispatcher.UnhandledException event, otherwise you can tie into the AppDomain.UnhandledException event:
Dispatcher.CurrentDispatcher.UnhandledException += HandleDispatcherException;
someDispatcher.UnhandledException += HandleDispatcherException;
AppDomain.CurrentDomain.UnhandledException += HandleAppDomainException;

Related

MVVM-Calling commands on child viewModel

Iam using MVVM and have a main window with Close button and it is bound to the MainWindowViewModel's ICommand command.
In the main window there are two UserControl1 and UserControl2 which is bound to viewmodels UserControlVM1 and UserControlVM2 respectively.
UserControlVM1 and UserControlVM2 has command named CleanUp that will clean up the resources.
So Whenever the close button is clicked on the mainwindow, i wanted to call the CleanUp command of Usercontrol viewmodels. How can we do this in XAML or any other alternatives?
A common implementation for communication between ViewModels is the Mediator Pattern which describes an object common between your ViewModels providing a Publish/Subscribe model. When an Event of interest occurs in an object it publishes a notification to the Mediator, one or more objects that are subscribed to that particular Event of the Mediator are then notified of the Event occurring in the original object.
Mediator Pattern Example
You should consider a view model first approach, in which case the MainWindowViewModel would have references to the UserControlVM1 and UserControlVM2, and can call the CleanUp methods directly.
You should consider using an MVVM framework if you're using MVVM.
You could inspire yourself from a technique from Prism's developer guide.
In Patterns and Practices' Prism Framework, CompositeCommand allows several ViewModel to register their own command against a single CompositeCommand, so that all can be called with one single call.
You'd also need this global class that is referenced in all your ViewModels, but not necessarily a static one since you don't have loose coupled modules.

Is this an acceptable way for a VM to respond to a property-change in another VM?

Suppose I have 2 VM classes that implement INotifyPropertyChanged (or Prism NotificationObject in this case) and I want one VM to respond to a property changing in the other VM?
Suppose these are both child VMs as properties on a parent VM, what are some ways I could wire them up from the parent VM without using event aggregator / mediator?
I plan to have an ICommand (a PRISM DelegateCommand) exposed by the listening VM wired up to the PropertyChanged event of the other VM, via the parent VM.
Firstly, is this an acceptable way to do it and secondly, how do I wire-up an ICommand to an event? Do I have to use an attached behavior eg programmatic EventToCommand or similar or is there a more straight-forward way to do it?
Secondly, is this an acceptable way to do this, within the philosophy of MVVM?
It's more straight-forward -- since your event listener has full access to the target class, you can invoke the method/command directly.
sourceVM.PropertyChanged += (sender, args) => {
if (args.PropertyName.Equals("Property to listen for"))
{
targetVM.Method();
}
};
Or, if the target needs to be an ICommand and not a regular method, then use targetVM.Command.Execute(null); instead.
I would also suggest creating a custom event in your source class, so that you're not relying on OnPropertyChanged and the property name "magic string".
As far as the philosophy of MVVM and good design, I think it does deviate somewhat, because now your two view models are more tightly coupled. That's not to say the approach is bad necessarily, but it does seem like Prism's event aggregator might be a better choice.

Initiate change of a DependencyProperty of a ViewModel with a Event of another Thread

I want to change a DependencyProperty of my ViewModel from a class which connects the application to a database.
This class raises events which should initiate a change of some properties in my ViewModel.
How can I realize that? I don't have the Dispatcher of the View.
I'm assuming you don't really have dependency properties on your viewmodels but rather normal C# properties which raises the PropertyChanged event.
If so, you should be fine already. Modify your properties from your background thread (normal concurrency issues apply obviously) and when they are bound to a WPF element's Dependency Property the runtime system will take care of marshalling the change to the proper thread (by using the view's Dispatcher object)
This works for normal properties, I'm not sure it works for ObservableCollections.
There are also different approaches for doing the marshalling inside the viewmodels. The simplest way is to just store the value of Dispatcher.CurrentDispatcher in your viewmodel's constructor. This works as long as your viewmodels are created on the UI thread.
One immediate solution to the problem is to capture the view's Dispatcher and store it on the view model when you create it, so you can Invoke/BeginInvoke the change to it in response to the event.
That being said, you should consider making your viewmodels use INotifyPropertyChanged with CLR properties rather than DependencyProperties to avoid issues like this. That way, any thread can make changes to your viewmodel and have the results reflected in the view.

WPF - Handling events from user control in View Model

I’m building a WPF application using MVVM pattern (both are new technologies for me). I use user controls for simple bits of reusable functionality that doesn’t contain business logic, and MVVM pattern to build application logic. Suppose a view contains my user control that fires events, and I want to add an event handler to that event. That event handler should be in the view model of the view, because it contains business logic. The question is – view and the view model are connected only by binding; how do I connect an event handler using binding? Is it even possible (I suspect not)? If not – how should I handle events from a control in the view model? Maybe I should use commands or INotifyPropertyChanged?
Generally speaking, it is a good MVVM-practice to avoid code in code behind, as would be the case if you use events in your user controls. So when possible, use INotifyPropertyChanged and ICommand.
With that said, depending on your project and how pragmatic you are, some times it makes more sense to use the control's code behind.
I have at a few occasions used something like this:
private void textBox1_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
MyViewModel vm = this.DataContext as MyViewModel;
vm.MethodToExecute(...);
}
You could also consider Attached Command Behaviour, more info about this and implementations to find here:
Firing a double click event from a WPF ListView item using MVVM

When to unhook events in Silverlight

One-line summary: What is the best practice for unhooking event handlers created in the constructor of a UserControl in Silverlight2?
Background:
I am currently building a line-of-business application in Silverlight2. As Silverlight is a browser plugin, there is no concept of a Window - everything is done within UserControls. The way I'm handling different "forms" in the application is to have a top-level usercontrol that contains a Viewbox. To show different forms, I set the Child property of the Viewbox to different UserControls. My app has a singleton PageManager class that is called to open and close forms. The forms (UserControls) are stored in a stack. Opening a form puts it on the top of the stack, closing it removes it from the stack and shows the one below it.
I'm trying to follow the Model-View-ViewModel pattern. In each form (derived from UserControl), I have a ViewModel that manages all the data for the View. The ViewModel exposes events so the UI can be notified when operations such as load and save have completed.
In my form, I subscribe to the event in the constructor, after I've got the ViewModel
public partial class MyPage : UserControl
{
public MyViewModel ViewModel{get; set;}
// other constructors, which create the viewmodel and call the constructor below.
public MyPage(MyViewModel viewModel)
{
InitializeComponent();
ViewModel = viewModel;
this.LayoutRoot.DataContext = this.ViewModel;
// subscribe to event so we can do stuff
this.ViewModel.LoadCompleted += new MyViewModel.LoadCompletedEventHandler(ViewModel_LoadCompleted);
}
My question is: Now that I've subscribed to this event, when do I remove the handler? Do I create a destructor and do it there, or does that create a chicken-and-egg situation where the garbage collector wont destroy the object until all references (ie: the event handlers) are gone? Do I create an interface that the forms must implement that specifies an UnhookEvents function that's called when the form is closed by the PageManager?
Edit: Thanks for the responses. What about the situation where the ViewModel lasts longer than the form (UserControl)? Part of my app allows users to create what is quite a complex structure, but in 95% of cases it's much simpler. What I've did was create 2 forms that use the same ViewModel. Users can start filling out the simple form, then switch to advanced mode, which creates a new form, passing the ViewModel to it.
In the simple setup form:
private void AdvancedSessionSetupButton_Click(object sender, RoutedEventArgs e)
{
PageManager.GetPageManager().Close(this);
PageManager.GetPageManager().Open(new CreateSessionPage(this.ViewModel), "Create Session");
}
In the advanced setup form:
private void BasicSessionSetupButton_Click(object sender, RoutedEventArgs e)
{
PageManager.GetPageManager().Close(this);
PageManager.GetPageManager().Open(new CreateBasicSessionPage(this.ViewModel), "Create Session");
}
After PageManager.Close, the only things referencing the form are the events within the ViewModel. I guess that's where I should be unhooking them.
A destructor, more commonly known to C# programmers as Finalizers, is not necessary in this case. Assuming that ViewModel_LoadCompleted is a member function, it contains a pointer to "this" which you are giving to the ViewModel object which is fully contained by "this". The garbage collector should intelligently ignore this.
In this case, the correct thing to do is to not waste time unbinding them.
In general, you need to unbind an event handler when you pass "this" (explicitly, or implicitly) to some object which will hold that reference longer than the intended lifetime of "this". For example, if you set a handler on a parent control's event. Now the parent has a reference to you via the handler as well as in its Children controls collection. In this case, you should unbind when you are removed from the parent.
When in doubt, implement IDisposable and unbind in the call to Dispose().
Events are automatically unbinded when the garbage collector goes through your object.
But you can explicitly unbind them with the "-=" syntax at anytime:
this.ViewModel.LoadCompleted -= ViewMode_LoadCompleted;
You can implement a destructor:
~MyPage
{
this.ViewModel.LoadCompleted -= ViewMode_LoadCompleted;
}

Resources