两个视图模型之间的通信

5

我是一个在MVVM设计模式方面的新手,并且有以下这些视图模型:

ClassAViewModel

public class ClassAViewModel : INotifyPropertyChanged
    {
        private int _nbre = 0;

        public int Nbre
        {
            get
            {
                return _nbre;
            }
            set
            {
                _nbre = value;
                PropertyChanged(this, new PropertyChangedEventArgs("Nbre"));
            }
        }

        #region Events
        public event PropertyChangedEventHandler PropertyChanged;
        #endregion

    }

还有 ClassBViewModel

 PUBLIC class ClassBViewModel: INotifyPropertyChanged
    {
        private Boolean _IsBiggerthanFive = false;

        public bool IsBiggerthanFive
        {
            get
            {
                return _IsBiggerthanFive;
            }
            set
            {
                _IsBiggerthanFive = value;
                PropertyChanged(this, new PropertyChangedEventArgs("IsBiggerthanFive"));
            }
        }

        #region Events
        public event PropertyChangedEventHandler PropertyChanged;
        #endregion

    }

我需要知道两个视图模型之间是否存在通知机制,即在我的情况下,如果第一个视图模型中的_nbre > 5,则会通知第二个视图模型并更改_IsBiggerthanFive的值。所以:

  1. 如何使两个视图模型之间相互通信而无需在其中一个中实例化另一个?
  2. 完成这项任务的最佳方法是什么?

1
最直接的方法可能是创建一个包含每个实例的ViewModel,然后连接事件以在它们之间传递数据。 - Andrew
这个问题的适当设计模式是中介者。http://en.wikipedia.org/wiki/Mediator_pattern - Gjeltema
2
另一种方法是使用Prism及其EventAggregator类。然后,ViewModel A可以引发一个事件,而ViewModel B可以订阅该事件,而不知道/关心谁引发了该事件。 - Mike Burdick
2个回答

3

我同意其他评论者的观点,调解器/发布-订阅/事件聚合器/信使是一个不错的选择。如果您没有使用内置解决方案的MVVM框架,那么我建议使用利用响应式扩展的这种简单方法

public class EventPublisher : IEventPublisher
{
    private readonly ConcurrentDictionary<Type, object> subjects
        = new ConcurrentDictionary<Type, object>();

    public IObservable<TEvent> GetEvent<TEvent>()
    {
        var subject =
            (ISubject<TEvent>) subjects.GetOrAdd(typeof (TEvent),
                        t => new Subject<TEvent>());
        return subject.AsObservable();
    }

    public void Publish<TEvent>(TEvent sampleEvent)
    {
        object subject;
        if (subjects.TryGetValue(typeof(TEvent), out subject))
        {
            ((ISubject<TEvent>)subject)
                .OnNext(sampleEvent);
        }
    }
}

这是你整个事件聚合器。将其实例传递到每个视图模型中,并将其存储为引用。然后创建一个类来存储您的事件细节,比如说“ValueChangedEvent”:

public class ValueChangedEvent
{
    public int Value
    {
        get { return _value; }
    }
    private readonly int _value;

    public ValueChangedEvent(int value)
    {
        _value = value;
    }
}

从第一个视图模型开始就像这样发布:

set
{
    _nbre = value;
    PropertyChanged(this, new PropertyChangedEventArgs("Nbre"));
    _eventPublisher.Publish(new ValueChangedEvent(value));
}

使用GetEvent在另一个类中订阅:

public class ClassBViewModel: INotifyPropertyChanged, IDisposable
{
    private readonly IDisposable _subscriber;

    public ClassBViewModel(IEventPublisher eventPublisher)
    {
        _subscriber = eventPublisher.Subscribe<ValueChangedEvent>(next => 
        {
            IsBiggerthanFive = next.Value > 5;
        });
    }

    public void Dispose()
    {
        _subscriber.Dispose();
    }
}

1

一个信使服务是一种解决方案。MVVM Light Toolkit有此实现。您可以使用它来监听视图模型中的特定类型的消息,并通过信使处理它。http://www.mvvmlight.net/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接