control if windows is active in shell view model

Dec 29, 2010 at 5:05 PM
Edited Dec 29, 2010 at 5:34 PM

I would be very happy if someone explain the following situations. I open new wpf window from main view model from method with shell view model.

I open new window and add reference on this window to dictionary. I use dictionary on control if is window active or not.  My problem is :

I open new window, close this window and then I want reactivate this window but I dont’t know if I close window (click on X ) is only deactivate or "not alive".

 Shell:

 

    [Export(typeof(IShellViewModel))]
    public class ShellViewModel : Conductor<object>, IShellViewModel
    {
        private IWindowManager _windowManager;
        private Dictionary<string, object> _activeChatScreen;

       
       [ImportingConstructor]
        public ShellViewModel(IWindowManager windowManager)
        {
            _windowManager = windowManager;
           _activeChatScreen=new Dictionary<string, object>();
        }

        //with this method I open new chat screen
        public void ShowChatScreen(DetailData oponent, BitmapImage avatarImage)
        {
            //if dic doesn’t contains refrence on chat screen
            if(!_activeChatScreen.ContainsKey(oponent.Info.Nick))
            {
                //create chat screen
                var chatScreen = IoC.Get<IChatViewModel>();

                //init chat screen
                chatScreen.Initialize(oponent, avatarImage);

                _windowManager.Show(chatScreen);

                //add reference on chat screen to dic
                _activeChatScreen.Add(oponent.Info.Nick, chatScreen);
            }
                //dic contains refence on chat screen
            else
            {
                var chatScreen= _activeChatScreen[oponent.Info.Nick] as ChatViewModel;

                //chat screen is not active
                if(!chatScreen.IsActive)
                {
                    //HERE I WOULD LIKE ACTIVE CHAT SCREEN

                   //ActivateItem(chatScreen);
                   //_windowManager.Show(chatScreen);
                }
            }
        }

 

New screen is WPF window:

 

[Export(typeof(IChatViewModel))]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class ChatViewModel : Screen, IViewModelIdentity, IHandle<Rp>
{ }

 

I would like achieve behavior like in this pseudocode:

 

        public void ShowChatScreen(string SCREEN_ID)
        {
            if(! IS_SCREEN_EXIST(SCREEN_ID))
            {
                CREATE_SCREEN(SCREEN_ID);
                ACTIVE_SCREEN(SCREEN_ID);
            }

            if(!IS_SCREEN_ACTIVE(SCREE_ID))
            {
                ACTIVE_SCREEN(SCREEN_ID);
                //SHOW ON TOP
            }
            ELSE
            {
                //SHOW ON TOP
            }
        }

Also I think possible solution can be remove reference from dictionary if screen is deactivated but I think I must use event aggregator and publish on shell view model message when is screen deactivated.

 

What is the best way in my solution?

 

I thinking about rewrite Close event for CHAT SCREEN - wpf window. Something like this:

 

        public new void Close()
        {
            _mClose = true;
            base.Close();
        }

        private void Window_Closing(object sender, CancelEventArgs e)
        {
            if(_mClose)
            {
                return;
            }
            e.Cancel = true;
            Hide();
        }


And on closing event only hide window no close definitly.

Coordinator
Dec 29, 2010 at 5:51 PM

Have you looked at using Conductor<T>.Collection.OneActive instead of Conductor<T> ? Have a read through this article http://caliburnmicro.codeplex.com/wikipage?title=Screens,%20Conductors%20and%20Composition&referringTitle=Documentation

Dec 29, 2010 at 6:42 PM

I read this article before I asked this question. My new screens are not user control but single WPF window  so I use window manager on show WPF window no ActivateItem.

It is possible show new wpf window with method ActiveItem? I think that Conductor<IScreen>.Collection.OneActive  is helpful if you want show new scree as use control.

Coordinator
Dec 29, 2010 at 7:16 PM

Perhaps you can take the source for Conductor<T>.Collection.OneActive and use it to build your own conductor that uses the window manager to show or bring to front the window on activation.

Dec 29, 2010 at 8:25 PM
EisenbergEffect wrote:

Perhaps you can take the source for Conductor<T>.Collection.OneActive and use it to build your own conductor that uses the window manager to show or bring to front the window on activation.

I look ak source of this class but I think it will be quite complicated from. It doesn’t exist other way?


For example, this method active item.

                public override void ActivateItem(T item)
                {
                    if (item != null && item.Equals(ActiveItem))
                    {
                        OnActivationProcessed(item, true);
                        return;
                    }

                    ChangeActiveItem(item, false);
                }

It call OnActivationProcessed method from base class.

        protected virtual void OnActivationProcessed(T item, bool success)
        {
            if (item == null)
                return;

            ActivationProcessed(this, new ActivationProcessedEventArgs
            {
                Item = item,
                Success = success
            });
        }
But I haven’t any idea where in this class use window manager.  :(

Nov 27, 2013 at 9:51 PM
So what happened next? How did you solve the issue? I have same problem. Is there any answer please?