MVVM dialog service - problems closing dialog from the vM

Topics: Prism v2 - Silverlight 2, Prism v2 - Silverlight 3, Prism v2 - Silverlight 4, Prism v2 - WPF 4, Prism v4 - Silverlight 4
Sep 16, 2010 at 4:32 PM

Hi

Uing the blog post sample

http://blog.roboblob.com/2010/01/19/modal-dialogs-with-mvvm-and-silverlight-4/

I copied it an created a dialog service for my silverlight project and it all seems to work fine.  My problem is I want to close some of my dialogs from the viewmodel , which would entail using the event aggregator to publish an event to close childwinows in the viewmodel.  When this event is published the Suscriber in the dialog service could then close the dialog

the issue i am having is how do I create a delegate sub or function that passes the instance of the dialog that neesd to be closed in the function that intially showed the dialog.  My code is below

Namespace SilverlightPlayground.DialogManagerService.Services 
    Public Class DialogManager 
        ''' <summary> 
        ''' Gets or sets the aggregator. 
        ''' </summary> 
        ''' <value>The aggregator.</value> 
        Private ReadOnly _eventAggregator As IEventAggregator 
 
        ''' <summary> 
        ''' Initializes a new instance of the <see cref="DialogManager"/> class. 
        ''' </summary> 
 
        Public Sub New() 
            _eventAggregator = ServiceLocator.Current.GetInstance(Of IEventAggregator)() 
 
            'register the dialogs as agregatted events 
            _eventAggregator.GetEvent(Of ErrorEvent)().Subscribe(AddressOf ShowErrorDialog) 
            _eventAggregator.GetEvent(Of ConfirmRequestEvent)().Subscribe(AddressOf ShowConfirmDialog) 
            _eventAggregator.GetEvent(Of ChooseColorEvent)().Subscribe(AddressOf ShowColorSelectorDialog) 
            _eventAggregator.GetEvent(Of UploadPhotoRequestEvent)().Subscribe(AddressOf ShowPhotoUploadDialog) 
            _eventAggregator.GetEvent(Of StatusEvent)().Subscribe(AddressOf ShowStatusDialog)
 
        End Sub 
 
      
 
'here is my delegate 
        Private Delegate Sub ClosePhotoUploadDialogDelegate(ByVal myDialog As PhotoUploadDialog) 
 
 
        ''' <summary> 
        ''' Shows Upload photos dialog and passes the profileID as well to the viewmodel 
        ''' </summary> 
        ''' <param name="StrProfileID">The ProfileID.</param> 
        Public Sub ShowPhotoUploadDialog(ByVal UploadPhoto As UploadPhoto) 
            Dim dialog As New PhotoUploadDialog()  'viewmodel is set in the dialaog  
 
            dialog.ProfileID = UploadPhoto.ProfileID 
            dialog.Show() 
        End Sub 
 
End Namespace

I can post my the subscrition event is not listed since i cannot figure out to create a delegate for it that knows what dialog to close.

 

c# code help is fine as well  thanks in advance
 

 

O lawal
Asp.net/Ajax Developer/Freelancer
Minneapolis Minnesota
Sep 17, 2010 at 7:28 PM

Hi O lawal,

I'm not sure what version of Prism you are using, so first of all in Prism v4 is using InteractionRequest and InteractionRequestTrigger for manipulating dialog boxes. You can find more information in the CHM of the latest drop of Prism: 

  • MVVM Advanced Scenarios (new), see Interaction Request section. 

Additionally, you could see how it works in the MVVM RI: <Prismv4InstallationDirectory>\MVVM RI

The following steps can help you to implement your scenario based on the aforementioned:

  1. Raise an InteractionRequest from the ViewModel. (code)
  2. Capture the request in the view via the InteractionRequestTrigger (xaml)
  3. Write a CloseWindowAction that attaches to the window. (code)
  4. Call the CloseWindowAction from the InteractionRequestTrigger (xaml)
  5. The caller that initiated the dialog should subscribe to closed event and clean up as needed. (code)

 

On the other hand, if you are using a previous version of Prism the following pseudo-code might help with the solution that you have implemented, you could use a similar code as is shown below (important details in bold):

public class ModalDialogService : IModalDialogService
{
      public Dictionary<TDialogViewModel, IModalWindow> activeDialogs = new Dictionary<TDialogViewModel, IModalWindow>();

      public void ShowDialog<TDialogViewModel>(IModalWindow view, TDialogViewModel viewModel, Action<TDialogViewModel> onDialogClose)
      {
        view.DataContext = viewModel;
        if (onDialogClose != null)
        {
          view.Closed += (sender, e) => onDialogClose(viewModel);
        }
        view.Show();
        activeDialogs[viewModel] = view;
      }
      public void ShowDialog<TDialogViewModel>(IModalWindow view, TDialogViewModel viewModel)
      {
        this.ShowDialog(view, viewModel, null);
      }
      public void CloseDialog<TDialogViewModel>(TDialogViewModel viewModel)
      {
        activeDialogs[viewModel].Close();
      }
    }
    public MyVM : TDialogViewModel
    {
        IModalDialogService modalService;
        CloseView()
        {
            modalService.CloseDialog(this);
        }
    }

Please let me know if this helps.

Fernando Antivero
http://blogs.southworks.net/fantivero