18

yesterday i used google to find a few ways to make an awesome reusable modal dialog in WPF with PRISM 4.1 and the MVVM pattern. I found some examples but i must say non of those were as "pretty" as i liked them to be.

This one: WPF Modal Dialog (no mvvm -> no use)

This is pretty nice: Showing Dialogs when using the MVVM Pattern (but still it's using a selfmade ServiceLocator which i don't need as i am using the IUnity Container. I could use the logic and rewrite it to Unity but that's not the "pretty" way in my honest opinion.

Well after a while searching the web for informations some blog (can't find the source right now) told me that the PRISM Framework got something called "interaction requests". So i checked out the prism documentation and found a small part under the topic "advanced mvvm scenarios" but the information given in the documentation aren't enough.

I'd like to know if somebody have any good example or any good blogpost about how to realize an awesome modal dialog in prism wpf with mvvm.

EDIT: Regarding the question in the comments:

What makes a modal dialog awesome?

Indeed a good question.

  1. It must be modal (while the dialog is open the rest of the UI should be freezed)
  2. The dialog view can have it's own viewmodel or at least i would like to give an instance of an object to the dialog view and return an object back to the parent view
  3. The view should be an own "xaml" file
  4. the dialogresult feature from .NET or at least a way to get a response what the user clicked in the dialog
darkdog
  • 3,805
  • 7
  • 37
  • 47
  • 2
    Uhm...what makes a modal dialog awesome? Ô.o Would be great if you could provide more technical requirements than this, let's say, *awesome* request. ;) – DHN Jan 23 '14 at 10:03
  • i edited my question with an answer to your question – darkdog Jan 23 '14 at 10:26
  • 1
    Aren't the list of features you've posted in your edit is already there in the basic WPF (no PRISM involved)? – noseratio Jan 23 '14 at 10:28
  • @Noseratio sure Window.ShowDialog() but try to make it in mvvm and afaik WPF runs only on 1 thread so it can't freeze the UI while the dialog is open. but i'm not sure about that – darkdog Jan 23 '14 at 10:40
  • 1
    `Window.ShowDialog()` doesn't freeze the UI. Rather, it blocks the user input from going into the parent window by disabling it, and then starts a nested modal message loop (new `Dispatcher` frame). All that happens on the same UI thread. So, it behaves much the same as WinForms `Form.ShowDialog()`. – noseratio Jan 23 '14 at 10:54
  • @darkdog By *UI should be freezed* you mean real freezed (no animations, databinding updates aso) or the dialog should have the focus and the user can see everything behind it but cannot access it. – DHN Jan 23 '14 at 12:31
  • yea the user should see the parent window in the background but no actions can be made there while the dialog is open – darkdog Jan 23 '14 at 12:37
  • 1
    @darkdog, freezing the UI and disabling it are two different things. Calling `Thread.Sleep(10000)` would freeze the whole UI. Calling `Window.ShowDialog()` would disable the user input from coming into the parent window, but it won't freeze it. You can even update the UI of the parent window from the modal dialog. Open Visual Studio and do Help About from the menu, is that the kind of the dialog you're looking for? – noseratio Jan 23 '14 at 13:05
  • @Noseratio check this: http://spin.atomicobject.com/2012/07/16/making-wpf-controls-modal-with-adorners/ thats the kind of modal dialog i need :) – darkdog Jan 23 '14 at 13:09
  • I see what you mean. You're not looking for a real modal window, rather for a new layer of UI in the main window. Check [this](http://stackoverflow.com/a/20930349/1768303), it's related. – noseratio Jan 23 '14 at 13:23
  • @Noseration i'll have a look at that. thank you. – darkdog Jan 23 '14 at 13:33
  • you should change your question when you want adorners instead of real modal dialogs... – blindmeis Jan 24 '14 at 06:46
  • i just wanted to show @Noseratio what i mean with "modal" – darkdog Jan 24 '14 at 07:02

4 Answers4

20

PRISM 5.0 came up with quick solution to show modal dialogs. Using PopupWindowAction.

<prism:InteractionRequestTrigger SourceObject="{Binding CustomPopupViewRequest, Mode=OneWay}">
    <prism:PopupWindowAction>
        <prism:PopupWindowAction.WindowContent>
            <views:CustomPopupView />
        </prism:PopupWindowAction.WindowContent>
    </prism:PopupWindowAction>
</prism:InteractionRequestTrigger>
Jawahar
  • 4,775
  • 1
  • 24
  • 47
  • 1
    This got me going in the right direction, but would benefit from a little more context: [Interactivity QuickStart Using the Prism Library 5.0 for WPF](https://msdn.microsoft.com/en-us/library/ff921081(v=pandp.40).aspx). – Paul Oct 24 '17 at 19:53
5

Interaction requests require a little more up-front work, but they are definitely the right way to go from the MVVM purist perspective...

I saw an example of how to do this with Prism in Karl Shifflett's MVVM In The Box training extension.

As I remember, the example was pretty rough around the edges, but it should set you in the right direction.

The problem with this kind of in-view "Dialog" is it doesn't allow the dialog to go outside the bounds of the parent window. On the plus side, you can do a lot of fancy layout and animation stuff.

Mark
  • 1,784
  • 16
  • 26
  • maeh.. this vs2010 template >: have to install 2010 for that :( – darkdog Jan 24 '14 at 08:02
  • 1
    All you really need is the source files, you don't have to install it. There's a SkyDrive link on the blog, the second Zip file in there has the code. Interaction request stuff is under `MVVMTraining\Acme Common\Acme.Prism\InteractionRequest` – Mark Jan 24 '14 at 08:45
  • that's what i were looking for! – darkdog Jan 24 '14 at 09:18
  • A warning though - that code is pretty clunky, especially around disabling the other controls on the Grid. There are probably better examples of how to do this elsewhere. I did it with a special InteractionContentControl in the view, instead of a Grid. – Mark Jan 24 '14 at 10:37
2

check my post from here

its simple, its mvvm, its a service and "all you have to do" in your viewmodel is:

var result = this.uiDialogService.ShowDialog("Dialogwindow title goes here", dialogwindowVM);
Community
  • 1
  • 1
blindmeis
  • 22,175
  • 7
  • 55
  • 74
  • to be fair i add some overloads lately to have some more like: bool? ShowDialog(string titel, object datacontext, double minHeigth = 0, double minWidth=0, double maxHeigth = double.PositiveInfinity, double maxWidth = double.PositiveInfinity); or bool? ShowDialog(string titel, object datacontext, ApplicationSettingsBase settings, string pathHeigthSetting, string pathWidthSetting, double minHeigth = 0, double minWidth = 0, double maxHeigth = double.PositiveInfinity, double maxWidth = double.PositiveInfinity); – blindmeis Jan 23 '14 at 14:54
  • The dialog service approach is poor, because... a) there is no way to choose the parent window for the dialog, and b) it should be the view's decision as to how a notification is displayed to the user. By using the dialog service, you're excluding the view from the picture altogether. – Mark Jan 23 '14 at 17:50
  • 1
    within my mvvm applications the VIEWMODEL decides when to open a modal dialog and the DATATEMPLATE of the modaldialogviewmodel decides how the modaldialog looks like. the parent of the modaldialog is simply the application mainwindow. so i dont see a poor approach, but a simple one :) – blindmeis Jan 24 '14 at 06:43
  • What if you have two top-level windows? – Mark Jan 24 '14 at 08:46
  • i do not have such situations, but what should happen when you open a modal dialog on your second top level window - you dont want to or you want access to the first top level window, while your modal dialog is open? – blindmeis Jan 24 '14 at 10:16
  • @blindmeis and you can always make use of PRISM's interaction requests to bind your dialogs to specific windows. https://msdn.microsoft.com/en-us/library/gg405494%28v=pandp.40%29.aspx#sec12 – Denis Brat Feb 18 '15 at 20:03
1

Caveat: I have not used PRISM and my answer assumes the use of just WPF and MVVM. I don't see this as a major problem as your list of requirements can be met without PRISM (which can be added on top of the basic solution at a later date anyway).

I have a project on Github which provides a custom FrameworkElement called ModalContentPresenter that allows modal content to be displayed. The element basically consists of two panes, one layered on top of the other. The back pane hosts your main content and the front pane hosts your modal content. The element has a dependency property which controls if the modal content is shown.

The element only provides the basic 'modal' functionality and is capable of hosting arbitrary content (like most WPF controls). If, for example, the modal content you are displaying is to look and behave like a window (have a title, close button, mouse drag etc.) then you will still need to do some work.

Here is how the ModalContentPresenter can address your requirements:

It must be modal (while the dialog is open the rest of the UI should be freezed)

The ModalcontentPresenter can be placed at any level within your visual hierarchy and anything behind the modal content (when displayed) will be inaccessible. The controls will still be enabled and will still react to any changes in the viewModel they are bound to but the user will be unable to navigate and interact with the controls using the mouse and keyboard.

The dialog view can have it's own viewmodel or at least I would like to give an instance of an object to the dialog view and return an object back to the parent view.

This Stackoverflow answer shows how I would recommend you achieve this.

The view should be an own "xaml" file

Both the primary and modal content can be defined using inline xaml or separate xaml files (such as a UserControl).

the dialogresult feature from .NET or at least a way to get a response what the user clicked in the dialog

The linked answer above shows how to get an 'answer' from your modal content. The basic premise is that your viewModels communicate normally (either directly or via other means such as an event bus). The only difference is that you just happen to be displaying your content in a way which means the user can only interact with the 'modal' data.

Community
  • 1
  • 1
Benjamin Gale
  • 12,977
  • 6
  • 62
  • 100