ProdigioM
ProdigioM

Reputation: 474

Handling "Popup" Window.xaml in PRISM

I'm developing a WPF application with MVVM and PRISM 7.

At some places I'd like to open a new Window.xaml with the click of a button.

So I've created that Window.xaml and am calling it like so when clicking that button/command:

private void OnInstrumentFinderCommand()
{
    var instrumentfinder = new InstrumentFinderWindow();
    var result = instrumentfinder.ShowDialog();
    if (result == true)
    {
        // logic here...   
    }
}

That works fine. The InstrumentFinderWindow opens up and I can interact with it.

But this breaks the loosely coupling which I want to achieve with MVVM.

I know how to use PRISM with Views and Modules, but cannot figure out how I have to handle the Window to achieve the same result as the code above, but loosely coupled resp. not calling it directly from within a ViewModel.

Is there even a way or do I have to handle this completely different?

EDIT: I just want to make clear, that I'm asking about a way to call a System.Windows.Window a MVVM/PRISM-way. Not about a "Yes/No/Cancel" popup dialog.

Upvotes: 1

Views: 1780

Answers (1)

Aleksei Petrov
Aleksei Petrov

Reputation: 1099

Calling popup dialog in PRISM-way can be done with Interaction User Experience.

This way is thoroughly described in PRISM documentation and there are bunch of examples how to do it properly in prism samples (25-NotificationRequest, 26-ConfirmationRequest, 27-CustomContent, 28-CustomRequest).

Declare InteractionRequest<T> property in your ViewModel:

public InteractionRequest<Notification> FindInstrumentRequest { get; }

Raise request inside command

private void OnInstrumentFinderCommand() {
    FindInstrumentRequest.Raise(
        new Notification(), 
        notification =>
        {
             //the dialog shown, logic here
        });
}

Add interaction trigger to the window View

<UserControl ...
             xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
             xmlns:prism="http://prismlibrary.com/">

    <i:Interaction.Triggers>
        <prism:InteractionRequestTrigger SourceObject="{Binding FindInstrumentRequest}">
            <prism:PopupWindowAction IsModal="True" CenterOverAssociatedObject="True">
                <prism:PopupWindowAction.WindowContent>
                    <views:InstrumentFinderWindow />
                </prism:PopupWindowAction.WindowContent>
            </prism:PopupWindowAction>
        </prism:InteractionRequestTrigger>
    </i:Interaction.Triggers>

...

</UserControl>

Implement IInteractionRequestAware interface by InstrumentFinderWindowViewModel and finish interaction with FinishInteraction invoking.

public partial class InstrumentFinderWindowViewModel: UserControl, IInteractionRequestAware
{
    private void SelectInstrument()
    {
        FinishInteraction?.Invoke();
    }

    public Action FinishInteraction { get; set; }
    public INotification Notification { get; set; }
}

You can create derived type of NotificationRequest and use it to pass data between window and dialog.

IMPORTANT ADDITION: This interaction mechanism will be removed in feature versions of PRISM. There is new way to handle dialog is being implemented now: DialogService. It is in pre-release version of PRISM library.

Upvotes: 2

Related Questions