Events Micro和事件聚合器-不需要的调用句柄方法

Events Micro和事件聚合器-不需要的调用句柄方法,events,caliburn.micro,eventaggregator,Events,Caliburn.micro,Eventaggregator,我有一个问题是在两个屏幕之间发布/处理消息 我的设想是: Messenger屏幕,它是主屏幕,发布在聊天屏幕上,它们是从屏幕。 Messenger视图模型处理来自服务器的消息 聊天屏幕可以在messenger屏幕上发布消息。和messanger视图模型在服务器上发送此消息 Messenger类如下所示: [Export("MessengerScreen", typeof(IMessengerViewModel))] public class MessengerViewModel : S

我有一个问题是在两个屏幕之间发布/处理消息

我的设想是:

  • Messenger屏幕,它是主屏幕,发布在聊天屏幕上,它们是从屏幕。 Messenger视图模型处理来自服务器的消息

  • 聊天屏幕可以在messenger屏幕上发布消息。和messanger视图模型在服务器上发送此消息

  • Messenger类如下所示:

     [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
            }
        }
    
       [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);
                }
            }
        }
    
    [导出(“信使屏幕”,类型(IMessengerViewModel))]
    公共类Messenger视图模型:Screen、iMessenger视图模型、IInitializable、IHandle
    {
    // ...
    [导入构造函数]
    公共信使视图模型(IPokecService服务,IEventAggregator eventAgg)
    {
    _eventAgg=eventAgg;
    _eventAgg.订阅(本);
    }
    //在从属屏幕上发布
    公开作废发布(Rp)
    {
    _事件集发布(rp);
    }
    //从从属屏幕处理消息
    公共无效句柄(Rp msg)
    {
    //发送到服务器
    }
    }
    
    从屏幕类如下所示:

     [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
            }
        }
    
       [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);
                }
            }
        }
    
    [导出(“聊天屏幕”,类型(IChatViewModel))]
    [PartCreationPolicy(CreationPolicy.NonShared)]
    公共类聊天视图模型:屏幕、可初始化、IHandle
    {
    [导入构造函数]
    公共聊天视图模型(IEventAggregator eventAgg)
    {
    _eventAgg=eventAgg;
    _eventAgg.订阅(本);
    }
    //仅在messenger屏幕上发布
    公开作废发布(Rp)
    {
    _事件集发布(rp);
    }
    //显示从messenger发布的消息
    公共空间把手(Rp)
    {
    AddBlockToConversation(rp);
    }
    //如果按enter键,则在messanger屏幕上发布
    公共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;
    添加区块转换(_yourRp);
    //在messanger屏幕上发布
    出版(u yourRp),;
    }
    }
    }
    
    我的问题是:

    第一个问题是:

    • 我从类中调用SendRp方法 ChatViewModel
    • 它在ChatViewModel中调用方法void Publish()
    • 然后是来自类Messenger ViewModel的调用方法void Handle()
    • 然后也调用方法void ChatViewModel类中的句柄()。
    我不想在ChatViewModel类中调用方法Handle()。为什么我将消息从ChatViewModel发送到Messenger ViewModel在ChatViewModel类中也称为方法句柄

    我的第二个问题是:

    我想从Messenger ViewModel发布消息,仅在特定的从属屏幕上发布

    MessgerVieModel具有队列内消息:{msg1、msg2、msg3、…、msgN}

    我想发表:

    • 从屏幕上的msg1#1
    • 从屏幕上的msg2#2
    • 从屏幕上的msg3#3
      • 我的解决方案: 我用修改类EventAggregator解决了问题。

        大概是这样的:

         [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
                }
            }
        
           [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 view模型都包含此界面:

        public interface  IViewModelIdentity
        {
            string ScreenIdentity { get; set; }
        }
        
        在偶数聚合器类中的Publish方法中,我有以下内容:

         public void Publish(Rp rp)
                {
        
                    WeakReference[] toNotify;
                    lock (_subscribers)
                        toNotify = _subscribers.ToArray();
        
                    Execute.OnUIThread(() =>
                    {
                        Log.Info("Publishing {0}.", rp);
                        var dead = new List<WeakReference>();
        
                        foreach (var reference in toNotify)
                        {
                            var target = reference.Target as IHandle<Rp>;
        
                            //GET ID OF SCREEN
                            var screenId = reference.Target as IViewModelIdentity;
        
                            //!
                            if (target != null && screenId != null)
                            {
                                if (screenId.ScreenIdentity=="screen on which we want to send a message")
                                {
                                    //PUBLISH ON SCREEN
                                    target.Handle(rp);
                                }
                            }
                            else if (!reference.IsAlive)
                                dead.Add(reference);
                        }
                        if (dead.Count > 0)
                        {
                            lock (_subscribers)
                                dead.Apply(x => _subscribers.Remove(x));
                        }
                    });
                }
        
        公共作废发布(Rp)
        {
        WeakReference[]提示;
        锁定(_订户)
        toNotify=_subscribers.ToArray();
        Execute.OnUIThread(()=>
        {
        Log.Info(“发布{0}.”,rp);
        var dead=新列表();
        foreach(toNotify中的var引用)
        {
        var target=参考。目标为IHandle;
        //获取屏幕的ID
        var screenId=引用。目标为IViewModelIdentity;
        //!
        if(target!=null&&screenId!=null)
        {
        if(screenId.ScreenIdentity==“我们要发送消息的屏幕”)
        {
        //在屏幕上发布
        目标手柄(rp);
        }
        }
        如果(!reference.IsAlive)
        添加(参考);
        }
        如果(死计数>0)
        {
        锁定(_订户)
        dead.Apply(x=>_.Remove(x));
        }
        });
        }