我在2个屏幕之间发布/处理消息有一个问题。
我的情景是:
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
}
}
Slave screen class看起来像这样:
[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);
}
}
}
我的问题是:
第一个问题是:
我不想在ChatViewModel类中调用方法Handle()。为什么我从ChatViewModel发送消息到MessengerViewModel在ChatViewModel类中也被称为方法句柄?
我的第二个问题是:
我想在某个从属屏幕上发布MessengerViewModel消息。
MessgerVieModel有队列消息:{msg1,msg2,msg3,...,msgN}
我想发布:
答案 0 :(得分:2)
我的解决方案: 我用修改类EventAggregator解决了我的问题。
这样的事情:
我的每个视图模型都会影响这个界面:
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));
}
});
}