简体   繁体   English

在Silverlight中发布和订阅事件

[英]Publish and subscribe events in silverlight

I am trying to understand a piece of code in a legacy silverlight application.In this code as you can see user can publish an event and subscribe to that event. 我试图理解旧版Silverlight应用程序中的一段代码。在这段代码中,您可以看到用户可以发布事件并订阅该事件。

while publishing event 发布事件时

 Messenger.Publish<ErrorInformationData>(MessageConstant.ShowMessageTechnicalError, 
 new ErrorInformationData(ServiceOperationName.ClaimsService_GetClaim, ServiceOperationOccurence.DataServiceUI));

then subscribing to that event 然后订阅该事件

Messenger.Subscribe<ErrorInformationData>(
                                this,
                                MessageConstant.ShowMessageTechnicalError,
                                 (result) =>
                                 {
                                     Messenger.Publish(MessageConstant.ShowMessage,
                                         new MessageData
                                         {
                                             Title = "Common$TechnicalError",
                                             MessageText = "Common$TechnicalErrorDetail",
                                             TextParameters = new object[] { result.OperationErrorCode.ToString() },
                                             MessageType = MessageData.MessageTypes.OK,
                                             OKAction = () =>
                                             {
                                                 HtmlPage.Window.Navigate(new Uri("", UriKind.Relative));
                                             },

                                             MessageLevel = MessageData.MessageLevels.Error
                                         }
                                     );
                                 }
                                );

Question is why do I need to use this framework where instead I can simply invoke a method.Also can anyone point to any documentation/tutorial regarding this communication. 问题是为什么我需要使用这个框架,而我可以简单地调用一个方法,任何人都可以指向与此通信有关的任何文档/教程。

Thanks @Nikosi for pointer, after more investigation I have found what's going on under the hood. 感谢@Nikosi的指导,经过更多调查,我发现了到底发生了什么。

So there is a IMessanger interface which contains signature of publish,subscribe and unsubscribe method. 因此,有一个IMessanger接口,其中包含发布,订阅和取消订阅方法的签名。

public interface IMessanger : IDisposable
{
       void Subscribe(IReceiver receiver, int messageId);     
       void Publish<TEventArgs>(object sender, TEventArgs e, int messageId) 
           where TEventArgs : EventArgs;     
       void Unsubscribe(IReceiver receiver, int messageId);
}

Now we define a class Messanger which implements the interface. 现在,我们定义一个实现接口的Messanger类。

public sealed class Messanger : IMessanger
   {
       private readonly Dictionary<int, List<IReceiver>> messageIdToReceiver;

       public Messanger()
       {
           this.messageIdToReceiver = new Dictionary<int, List<IReceiver>>();
       }

       public void Subscribe(IReceiver receiver, int messageId)
       {
           List<IReceiver> receivers;

           if (this.messageIdToReceiver.TryGetValue(messageId, out receivers))
           {
               receivers.Add(receiver);
           }
           else
           {
               this.messageIdToReceiver.Add(messageId, new List<IReceiver>() { receiver });
           }
       }

       public void Publish<TEventArgs>(object sender, TEventArgs e, int messageId) 
           where TEventArgs : EventArgs
       {
           List<IReceiver> receivers;

           if (this.messageIdToReceiver.TryGetValue(messageId, out receivers))
           {
               foreach (IReceiver receiver in receivers)
               {
                   IReceiver<TEventArgs> receiverToReceive = receiver as IReceiver<TEventArgs>;

                   if (receiverToReceive != null)
                   {
                       receiverToReceive.Receive(sender, e, messageId);
                   }
               }
           }
       }

       public void Unsubscribe(IReceiver receiver, int messageId) 
       {
           List<IReceiver> receivers;

           if (this.messageIdToReceiver.TryGetValue(messageId, out receivers))
           {
               if (receivers.Count > 1)
               {
                   receivers.Remove(receiver);
               }
               else if(receivers.Count == 1)
               {
                   this.messageIdToReceiver.Remove(messageId);
               }
           }
       }

       public void Dispose()
       {
           this.messageIdToReceiver.Clear();
       }
   }

 public interface IReceiver<TEventArgs> : IReceiver
       where TEventArgs : EventArgs
   {
       void Receive(object sender, TEventArgs e, int messageId);
   }

   public interface IReceiver : IDisposable
   {

   }

Now we can see the usage of the above,Defined two classes one is publishing the event and other one is receiving the event. 现在我们可以看到上面的用法,定义了两个类:一个是发布事件,另一个是接收事件。

public class PresenterA : IReceiver<EventArgs>, IDisposable
   {
       readonly IMessanger messanger;

       public PresenterA(IMessanger messanger)
       {
           this.messanger = messanger;
           this.messanger.Subscribe(this, (int)PubSubMsg.AppInstl);
       }

       public void Receive(object sender, EventArgs e, int messageId)
       {
           if ((PubSubMsg)messageId == PubSubMsg.AppInstl)
           {
               //Now that you received the message, update the UI, etc...
           }
       }

       public void Dispose()
       {
           this.messanger.Unsubscribe(this, (int)PubSubMsg.AppInstl);
       }
   }

   public class PresenterB
   {
       readonly IMessanger messanger;

       public PresenterB(IMessanger messanger)
       {
           this.messanger = messanger;
       }

       public void btnApplicationRemove(object sender, EventArgs e)
       {
           //Do what you need to do and then publish the message
           this.messanger.Publish<EventArgs>(this, e, (int)PubSubMsg.AppInstl);
       }
   }

   public enum PubSubMsg
   {
       AppInstl = 1
   }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM