views:

404

answers:

1

Hi

We have a Region in the Window tag of our shell, adding things to this region pops out another Window.

<Window x:Class="GTS.GRS.N3.Shell.Shell1"
 --removed namespace references for clarity
    cal:RegionManager.RegionName="{x:Static Constants:RegionNames.WindowRegion}">  

We're adding ViewModels to the Region Manager and then the View is attached via a data context so that the ViewModel knows nothing about the View i.e.

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"&gt;
    <DataTemplate DataType="{x:Type Model:CommunicationViewModel}">
       <v:CommunicationView />
    </DataTemplate>
</ResourceDictionary>

My question is how do I close the Pop up Window, I tried removing the ViewModel from the RegionManager - but this exceptions ... the View is a UserControl, but I need to close its Owner which is a new Window opened by the Region. I don't really want to have to hack it via the DataContext of the ViewModel.

Can anyone assist please?

+1  A: 

Andy,

It took me quite awhile to figure this one out myself.

The cleanest way to accomplish this is by using the DelegateCommand (or RelayCommand) and adding an event handler in the code that creates the window with window.Show().

        //===========================================================================
        // Define the View
        //===========================================================================
        Shell window = Container.Resolve<Shell>();

        //===========================================================================
        // Define the ViewModel
        //===========================================================================
        ShellViewModel windowVM = Container.Resolve<ShellViewModel>();

        //===========================================================================
        // When the ViewModel asks to be closed, close the View.
        //===========================================================================
        EventHandler handler = null;
        handler = delegate
        {
            windowVM.RequestClose -= handler;
            window.Close();
        };
        windowVM.RequestClose += handler;

        //===========================================================================
        // Set the ViewModel as the DataContext of the View
        //===========================================================================
        window.DataContext = windowVM;

        //===========================================================================
        // Display the View
        //===========================================================================
        window.Show();

I then use a Composite Event to notify the window's ViewModel (not the UserControl's) that it has a request to close. The assigned subscription handler for the composite event then calls this.OnRequestClose().

In the Constructor for the ViewModel:

    //subscribe to composite events
    _eventAggregator.GetEvent<WindowCloseEvent>().Subscribe(WindowClose);

In the body of the ViewModel:

    /// <summary>
    /// Private Event handler for WindowCloseEvent.
    /// </summary>
    private void WindowClose(bool value)
    {
        // Close the View
        this.OnRequestClose();
    }

See Josh Smith's excellent article on MSDN about using the M-V-VM pattern with WPF at http://msdn.microsoft.com/en-us/magazine/dd419663.aspx for more information.

Chuck Borcher