Frage

Ich habe ein Problem mit der Veröffentlichung/Handlungsnachrichten zwischen 2 Bildschirmen.

Mein Szenario ist:

  1. Messenger -Bildschirm, ist It Master -Bildschirm, veröffentlicht auf Chat -Bildschirmen, sie sind Sklavenbildschirme. Messenger -View -Modellhandle mit Nachrichten vom Server.

  2. Der Chat -Bildschirm kann Nachrichten auf dem Messenger -Bildschirm veröffentlichen. Und Messanger View -Modell senden diese Nachricht auf dem Server.

Messenger -Klasse sehen so aus:

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

Sklavenbildschirmklasse sehen so aus:

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

Meine Probleme sind:

Das erste Problem ist:

  • Ich rufe methode sendRP von Class ChatviewModel auf.
  • Es nennt die Methode void Publish () in ChatviewModel,
  • Dann ist die Call -Methode void Handle () von Class MessengerViewModel
  • und rufen Sie dann auch Methode void Handle () von der ChatViewModel -Klasse auf.

Ich möchte keine Call -Methode Handle () in der ChatviewModel -Klasse. Warum, wenn ich eine Nachricht von ChatviewModel an MessengerViewModel sende, wird auch in der ChatviewModel -Klasse als Methode -Handle bezeichnet?

Mein zweites Problem ist:

Ich möchte von MessengerViewModel -Nachricht nur auf einem bestimmten Sklavenbildschirm veröffentlichen.

Messgerviemodel haben in Warteschlangennachrichten: {Msg1, Msg2, Msg3, ..., Msgn}

Ich möchte veröffentlichen:

  • MSG1 auf Slave -Bildschirm Nr. 1.
  • MSG2 auf Slave -Bildschirm Nr. 2
  • ...
  • MSG3 auf Slave -Bildschirm #3
War es hilfreich?

Lösung

Meine Lösung: Ich habe mein Problem mit der Änderungsklasse EventAggregator gelöst.

Etwas wie das:

Jedes meine Ansichtsmodell imlementiert diese Schnittstelle:

public interface  IViewModelIdentity
{
    string ScreenIdentity { get; set; }
}

Und in der Veröffentlichung der Methode auch in der Aggregator -Klasse habe ich Folgendes:

 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));
                }
            });
        }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top