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
[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类中的句柄()。
- 从屏幕上的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));
}
});
}