Good or bad practice for Dialogs in wpf with MVVM?
I've been using an almost identical approach for several months now, and I'm very happy with it (i.e. I haven't yet felt the urge to rewrite it completely...)
In my implementation, I use a IDialogViewModel
that exposes things such as the title, the standad buttons to show (in order to have a consistent apparence across all dialogs), a RequestClose
event, and a few other things to be able to control the window size and behavior
If you are talking about dialogue windows and not just about the pop-up message boxes, please consider my approach below. The key points are:
- I pass a reference to
Module Controller
into the constructor of eachViewModel
(you can use injection). - That
Module Controller
has public/internal methods for creating dialogue windows (just creating, without returning a result). Hence to open a dialogue window inViewModel
I write:controller.OpenDialogEntity(bla, bla...)
- Each dialogue window notifies about its result (like OK, Save, Cancel, etc.) via Weak Events. If you use PRISM, then it's easier to publish notifications using this EventAggregator.
- To handle dialogue results, I'm using subscription to notifications (again Weak Events and EventAggregator in case of PRISM). To reduce dependency on such notifications, use independent classes with standard notifications.
Pros:
- Less code. I don't mind using interfaces, but I've seen too many projects where excessiveness of using interfaces and abstraction layers cause more trouble than help.
- Open dialogue windows through
Module Controller
is a simple way to avoid strong references and still allows to use mock-ups for testing. - Notification through weak events reduce number of potential memory leaks.
Cons:
- Not easy to distinguish required notification from others in the handler. Two solutions:
- send a unique token on opening a dialogue window and check that token in the subscription
- use generic notification classes
<T>
whereT
is enumeration of entities (or for simplicity it can be type of ViewModel).
- For a project should be an agreement about using notification classes to prevent duplicating them.
- For enormously large projects the
Module Controller
can be overwhelmed by methods for creating windows. In this case it's better to split it up in several modules.
P.S. I have been using this approach for quite a long time now and ready to defend its eligibility in comments and provide some examples if required.
This is a good approach and I used similar ones in the past. Go for it!
One minor thing I'd definitely do is make the event receive a boolean for when you need to set "false" in the DialogResult.
event EventHandler<RequestCloseEventArgs> RequestCloseDialog;
and the EventArgs class:
public class RequestCloseEventArgs : EventArgs
{
public RequestCloseEventArgs(bool dialogResult)
{
this.DialogResult = dialogResult;
}
public bool DialogResult { get; private set; }
}