C# 从MVVM角度处理消息循环

C# 从MVVM角度处理消息循环,c#,mvvm-light,C#,Mvvm Light,我的应用程序中有多个对象同时发送和接收相同的消息。例如:当用户在网格上拖放列、用户使用“网格设置”对话框以及用户加载其他报告时,可以更改网格的列顺序。因此网格既可以发送“Column Order Changed”消息,也可以接收该消息 有没有办法阻止网格获取自己的消息?因此,当用户拖动一个列时,网格会向所有感兴趣的侦听器发送一条“列顺序已更改”消息,但我不希望网格在订阅后收到回电。我可以使用谓词并在消息中嵌入一些发送者信息,但我想知道Mvvm Light是否能够处理这种情况本身。检查IMesse

我的应用程序中有多个对象同时发送和接收相同的消息。例如:当用户在网格上拖放列、用户使用“网格设置”对话框以及用户加载其他报告时,可以更改网格的列顺序。因此网格既可以发送“Column Order Changed”消息,也可以接收该消息


有没有办法阻止网格获取自己的消息?因此,当用户拖动一个列时,网格会向所有感兴趣的侦听器发送一条“列顺序已更改”消息,但我不希望网格在订阅后收到回电。我可以使用谓词并在消息中嵌入一些发送者信息,但我想知道Mvvm Light是否能够处理这种情况本身。

检查IMessenger Register方法的重载:

/// <summary>
/// Registers a recipient for a type of message TMessage.
///             The action parameter will be executed when a corresponding
///             message is sent. See the receiveDerivedMessagesToo parameter
///             for details on how messages deriving from TMessage (or, if TMessage is an interface,
///             messages implementing TMessage) can be received too.
/// 
/// <para>
/// Registering a recipient does not create a hard reference to it,
///             so if this recipient is deleted, no memory leak is caused.
/// </para>
/// 
/// </summary>
/// <typeparam name="TMessage">The type of message that the recipient registers
///             for.</typeparam><param name="recipient">The recipient that will receive
///             the messages.</param><param name="token">A token for a messaging
///             channel. If a recipient registers using a token, and a sender sends
///             a message using the same token, then this message will be delivered to
///             the recipient. Other recipients who did not use a token when
///             registering (or who used a different token) will not get the message.
///             Similarly, messages sent without any token, or with a different
///             token, will not be delivered to that recipient.</param><param name="receiveDerivedMessagesToo">If true, message types deriving from
///             TMessage will also be transmitted to the recipient. For example, if a SendOrderMessage
///             and an ExecuteOrderMessage derive from OrderMessage, registering for OrderMessage
///             and setting receiveDerivedMessagesToo to true will send SendOrderMessage
///             and ExecuteOrderMessage to the recipient that registered.
/// 
/// <para>
/// Also, if TMessage is an interface, message types implementing TMessage will also be
///             transmitted to the recipient. For example, if a SendOrderMessage
///             and an ExecuteOrderMessage implement IOrderMessage, registering for IOrderMessage
///             and setting receiveDerivedMessagesToo to true will send SendOrderMessage
///             and ExecuteOrderMessage to the recipient that registered.
/// </para>
/// </param><param name="action">The action that will be executed when a message
///             of type TMessage is sent.</param>
void Register<TMessage>(object recipient, object token, bool receiveDerivedMessagesToo, Action<TMessage> action);
//
///为一种类型的邮件TMessage注册收件人。
///当相应的
///消息已发送。请参阅ReceiveDerivedMessagesTo参数
///有关如何从TMessage派生消息的详细信息(或者,如果TMessage是一个接口,
///也可以接收实现TMessage的消息。
/// 
/// 
///注册收件人不会创建对其的硬引用,
///因此,如果删除此收件人,则不会导致内存泄漏。
/// 
/// 
/// 
///收件人注册的邮件类型
///对于。将接收的收件人
///消息。消息的令牌
///频道。如果收件人使用令牌注册,而发件人发送
///使用相同令牌的消息,则此消息将传递给
///收件人。当发生以下情况时未使用令牌的其他收件人:
///注册(或使用其他令牌的用户)将不会收到消息。
///类似地,不使用任何令牌或使用不同的
///令牌将不会传递给该收件人。如果为true,则从
///TMessage也将被传输到收件人。例如,如果SendOrderMessage
///以及从OrderMessage派生的ExecuteOrderMessage,注册OrderMessage
///将receiveDerivedMessagesToo设置为true将发送SendOrderMessage
///并向注册的收件人发送ExecuteOrderMessage。
/// 
/// 
///另外,如果TMessage是一个接口,那么实现TMessage的消息类型也将是
///传送给收件人。例如,如果SendOrderMessage
///以及一个ExecuteOrderMessage实现iordMessage,注册iordMessage
///将receiveDerivedMessagesToo设置为true将发送SendOrderMessage
///并向注册的收件人发送ExecuteOrderMessage。
/// 
///当消息被删除时将执行的操作
///发送类型为TMessage的消息。
无效寄存器(对象收件人、对象令牌、bool receiveDerivedMessagesToo、操作);
注:

消息传递通道的令牌。如果收件人使用令牌注册,而发件人使用相同的令牌发送消息,则此消息将传递给收件人。其他在注册时未使用令牌的收件人(或使用其他令牌的收件人)将不会收到邮件。类似地,不使用任何令牌或使用其他令牌发送的邮件也不会传递给该收件人


您可以做的是让该消息的其他寄存器使用令牌注册,然后在网格发送消息时使用该令牌发送。网格的注册不应该包括令牌。

是的,我看到了。但使用令牌的问题是,每个发布者都需要自己的令牌,而每个订阅者都需要订阅自己以外的每个令牌。这将变得相当混乱,并且很难维护您添加到系统中的更多发布者。在我的例子中,我有3个对象可以发送和接收,第四个对象只能接收。我可以使用exented Mvvm Light,这样当您发送消息时,您可以传递一个对象,如果该对象与注册时使用的收件人对象相同,则不会传递该消息。@MattS可能您的网格需要发布另一种类型的消息,一种它不订阅的类型。因为消息需要不同的处理,所以一定会有不同。每个发布者都会对同一消息有自己的风格,并且他们都需要订阅不同的风格。@MattS拦截网格列移动,e.取消它,但仍然发送消息如何。然后让处理程序进行移动,就像从其他任何地方移动一样。将GetHashCode()作为ID添加到消息中如何。如果是你的身份证,忽略它。或者向消息中的对象添加一个实例(例如,对象发送者{get;set;},如果是,则忽略它)。