Prism Custom Confirmation Interaction

Main thing is, when you raise the interaction, provide a callback that is triggered when the interaction is finished. This callback gets the notification back and your interaction should have stored all potentially interesting return values there.

Here’s an example…

Relevant parts of the ViewModel:

public InteractionRequest<SelectQuantityNotification> SelectQuantityRequest
{
    get;
}

// in some handler that triggers the interaction
SelectQuantityRequest.Raise( new SelectQuantityNotification { Title = "Load how much stuff?", Maximum = maximumQuantity },
    notification =>
    {
        if (notification.Confirmed)
            _worldStateService.ExecuteCommand( new LoadCargoCommand( sourceStockpile.Stockpile, cartViewModel.Cart, notification.Quantity ) );
    } );

… and from the View:

<i:Interaction.Triggers>
    <interactionRequest:InteractionRequestTrigger 
        SourceObject="{Binding SelectQuantityRequest, Mode=OneWay}">
        <framework:FixedSizePopupWindowAction>
            <interactionRequest:PopupWindowAction.WindowContent>
                <views:SelectSampleDataForImportPopup/>
            </interactionRequest:PopupWindowAction.WindowContent>
        </framework:FixedSizePopupWindowAction>
    </interactionRequest:InteractionRequestTrigger>
</i:Interaction.Triggers>

Additionally, we need a class to hold the data that’s passed around, and a ViewModel/View pair for the interaction itself.

Here’s the data holding class (note that Maximum is passed to the interaction, and Quantity returned from it):

internal class SelectQuantityNotification : Confirmation
{
    public int Maximum
    {
        get;
        set;
    }

    public int Quantity
    {
        get;
        set;
    }
}

This is the View of the interaction popup:

<UserControl x:Class="ClientModule.Views.SelectSampleDataForImportPopup"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:prism="http://prismlibrary.com/"
         prism:ViewModelLocator.AutoWireViewModel="True"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
    <StackPanel Orientation="Vertical">
        <TextBlock>
            Amount: <Run Text="{Binding Quantity}"/>
        </TextBlock>
        <Slider Orientation="Horizontal" Minimum="0" Maximum="{Binding Maximum}" Value="{Binding Quantity}" TickPlacement="BottomRight"/>
        <Button Content="Ok" Command="{Binding OkCommand}"/>
    </StackPanel>
</UserControl>

and it’s ViewModel:

internal class SelectSampleDataForImportPopupViewModel : BindableBase, IInteractionRequestAware
{
    public SelectSampleDataForImportPopupViewModel()
    {
        OkCommand = new DelegateCommand( OnOk );
    }

    public DelegateCommand OkCommand
    {
        get;
    }

    public int Quantity
    {
        get { return _notification?.Quantity ?? 0; }
        set
        {
            if (_notification == null)
                return;
            _notification.Quantity = value;
            OnPropertyChanged( () => Quantity );
        }
    }

    public int Maximum => _notification?.Maximum ?? 0;

    #region IInteractionRequestAware
    public INotification Notification
    {
        get { return _notification; }
        set
        {
            SetProperty( ref _notification, value as SelectQuantityNotification );
            OnPropertyChanged( () => Maximum );
            OnPropertyChanged( () => Quantity );
        }
    }

    public Action FinishInteraction
    {
        get;
        set;
    }
    #endregion

    #region private
    private SelectQuantityNotification _notification;

    private void OnOk()
    {
        if (_notification != null)
            _notification.Confirmed = true;
        FinishInteraction();
    }
    #endregion
}

Leave a Comment