Caliburn.Micro and event aggregator -unwanted call handle method

Dec 25, 2010 at 1:22 PM

Hi, I have one problem with publish/handle messages between 2 screens.

My scenario is:

  1. Messenger screen, is it master screen, publish on chat screens, they are slave screens. Messenger view model handle with messages from server.

  2. Chat screen can publishes messages on messenger screen. And messanger view model send this message on server.

Messenger class look like this:

 [Export("MessengerScreen", typeof(IMessengerViewModel))]
    public class MessengerViewModel : Screen, IMessengerViewModel, IInitializable<Account>, IHandle<Rp>
    {
        // ...

        [ImportingConstructor]
        public MessengerViewModel(IPokecService service, IEventAggregator eventAgg)
        {
            _eventAgg = eventAgg;
            _eventAgg.Subscribe(this);
        }


        //publish on slave screen 
        public void Publish(Rp rp)
        {
            _eventAgg.Publish(rp);
        }

        //handle msg from slave screen
        public void Handle(Rp msg)
        {
            //send to server
        }
    }

Slave screen class look like this:

[Export("ChatScreen", typeof(IChatViewModel))]
    [PartCreationPolicy(CreationPolicy.NonShared)]
    public class ChatViewModel : Screen, IInitializable<DetailData>, IHandle<Rp>
    {
        [ImportingConstructor]
        public ChatViewModel(IEventAggregator eventAgg)
        {
            _eventAgg = eventAgg;
            _eventAgg.Subscribe(this);
        }

        //publish only on messenger screen
        public void Publish(Rp rp)
        {
            _eventAgg.Publish(rp);
        }

        //show message from published from messenger
        public void Handle(Rp rp)
        {
            AddBlockToConversation(rp);
        }

        //if enter is pressed publish on messanger screen
        public void SendRp(KeyEventArgs e)
        {
            if (e.Key == Key.Enter && !string.IsNullOrEmpty(RpText))
            {
                _yourRp.Time = String.Format("{0:yyyy-MM-dd HH:mm:ss}", DateTime.Now);

                _yourRp.RpText = RpText;

                AddBlockToConversation(_yourRp);


                //publish on messanger screen
                Publish(_yourRp);
            }
        }
    }

My problems are:

First problem is:

  • I call method SendRp from class ChatViewModel.
  • It calls method void Publish() in ChatViewModel,
  • then is call method void Handle() from class MessengerViewModel
  • and then call also method void Handle() from ChatViewModel class.

I don’t want call method Handle() in ChatViewModel class. Why if I send message from ChatViewModel to MessengerViewModel is also called method Handle in ChatViewModel class?

My second problem is:

I would like publish from MessengerViewModel message on only certain slave screen.

MessgerVieModel have in queue messages: {msg1, msg2, msg3, ..., msgN}

I would like publish:

  • msg1 on slave screen #1.
  • msg2 on slave screen #2
  • ...
  • msg3 on slave screen #3
Coordinator
Dec 25, 2010 at 8:42 PM

You may need something more customized than what is provided out of the box for your scenario. Take a look at the EventAggregator source code and see if you can modify that for your needs and plug it into your IoC. If so, then you can keep your application code as is and get the behavior you desire. If not, you may need to investigate a more custom solution.

Dec 26, 2010 at 4:14 PM
EisenbergEffect wrote:

You may need something more customized than what is provided out of the box for your scenario. Take a look at the EventAggregator source code and see if you can modify that for your needs and plug it into your IoC. If so, then you can keep your application code as is and get the behavior you desire. If not, you may need to investigate a more custom solution.

Thank for idea. I solved my problem with modification class EventAggregator.