Open new Window from view model

Dec 21, 2010 at 2:06 PM
Edited Dec 21, 2010 at 2:28 PM

Hi I have a beginner problem. I have shell (it is wpf window) and in this shell is screen (it is an user control / view model).

I would like open new window from  view model, not show user control in shell.

So I create new window - ChatView

 

<Window x:Class="Spirit.Views.ChatView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:extToolkit="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit.Extended" Title="ChatView" Height="545" Width="763">
    <Grid Margin="4,4,4,4">
     </Grid>
</Window>

Export ChatViewModel with MEF.

    public interface IChatViewModel
    {
        
    }

    [Export("ChatScreen",typeof(IChatViewModel))]
    public class ChatViewModel
    {
        
    }


In view model I have this method:

        public IEnumerable<IResult> OpenNewWindow()
        {
            yield return new ShowScreen.ShowScreen("ChatScreen");
        }

With ShowScreen class help me Mr.Marco Amendola (http://caliburnmicro.codeplex.com/Thread/View.aspx?ThreadId=238908), It look likes this:

    public class ShowScreen : IResult
    {
        readonly Type _screenType;
        readonly string _name;

        [Import]
        public IShellViewModel Shell { get; set; }

        Action<object> _initializationAction = screen => { };

        public ShowScreen InitializeWith<T>(T argument) 
        {
            _initializationAction = screen =>
                                        {
                                            var initializable = screen as IInitializable<T>;
                                            if (initializable != null)
                                                initializable.Initialize(argument);
                                        };
		return this;
	    } 

        public ShowScreen(string name)
        {
            _name = name;
        }

        public ShowScreen(Type screenType)
        {
            _screenType = screenType;
        }

        public void Execute(ActionExecutionContext context)
        {
            var screen = !string.IsNullOrEmpty(_name)
                ? IoC.Get<object>(_name)
                : IoC.GetInstance(_screenType, null);

            _initializationAction(screen);

            Shell.ActivateItem(screen);
            Completed(this, new ResultCompletionEventArgs());
        }

        public event EventHandler<ResultCompletionEventArgs> Completed = delegate { };

        public static ShowScreen Of<T>()
        {
            return new ShowScreen(typeof(T));
        }
    }

My problem is if I try show new window it doesn’t works, it works only if I show new user control in shell(window).

I would like achieve behavior something like in skype. You have a main window with listbox, you double clicked on item and it show new chat window.

Main window can publish with EventAggregator on chat window and also chat window can publish on main window. This is my goal.

I know that I can not use class ShowScreen on showing new Window. I would like to know what is correct way to create new  window  from view model and inject  event aggregator
to this vie model.

Any advice? Thank for your help and time.



 

Dec 21, 2010 at 5:40 PM

You might replace 

Shell.ActivateItem(screen);

with

IoC.Get<IWindowManager>().Show(screen);

in the ShowScreen class.
Just out of completeness, you may also call IWindowManager.Show in your VM code directly.

 

Dec 22, 2010 at 5:27 PM

Thank for your explanation.