2

2つの画面間でメッセージを公開/処理する際に1つの問題があります。

私のシナリオは次のとおりです。

  1. メッセンジャー画面、マスター画面、チャット画面での公開、スレーブ画面です。サーバーからのメッセージを処理するメッセンジャービューモデル。

  2. チャット画面はメッセンジャー画面にメッセージを公開できます。そして、メッセンジャービューモデルはこのメッセージをサーバーに送信します。

メッセンジャークラスは次のようになります。

 [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);
            }
        }
    }

私の問題は次のとおりです。

最初の問題は次のとおりです。

  • クラスChatViewModelからメソッドSendRpを呼び出します。
  • ChatViewModelのメソッドvoidPublish()を呼び出します。
  • 次に、MessengerViewModelクラスからメソッドvoid Handle()を呼び出します
  • 次に、ChatViewModelクラスからメソッドvoid Handle()も呼び出します。

ChatViewModelクラスでメソッドHandle()を呼び出したくありません。ChatViewModelからMessengerViewModelにメッセージを送信すると、ChatViewModelクラスのメソッドHandleとも呼ばれるのはなぜですか?

私の2番目の問題は:

特定のスレーブ画面でのみMessengerViewModelメッセージから公開したい。

MessgerVieModelにはキューメッセージがあります:{msg1、msg2、msg3、...、msgN}

公開したい:

  • スレーブ画面#1のmsg1。
  • スレーブ画面#2のmsg2
  • ..。
  • スレーブ画面#3のmsg3
4

1 に答える 1

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));
                }
            });
        }
于 2010-12-26T16:35:58.027 に答える