【问题标题】:Communication between two viewmodels两个视图模型之间的通信
【发布时间】:2015-02-11 15:55:08
【问题描述】:

我是 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. 完成这项任务的最佳方法是什么?

【问题讨论】:

  • 最直接的方法可能是创建一个包含每个实例的 ViewModel,然后连接事件以在它们之间传递数据。
  • 合适的设计模式是调解器。 en.wikipedia.org/wiki/Mediator_pattern
  • 另一种方法是使用 Prism 及其 EventAggregator 类。然后 ViewModel A 可以引发一个事件,而 ViewModel B 可以订阅该事件并且不知道/关心谁引发了事件。

标签: c# .net wpf winforms mvvm


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    我同意其他评论者的观点,即调解器/发布订阅/事件聚合器/信使是一个不错的选择。如果你没有使用带有内置解决方案的 MVVM 框架,那么我推荐this simple approach that takes advantage of the Reactive extensions

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-28
      • 2019-11-24
      • 2014-10-11
      • 2011-09-06
      • 1970-01-01
      • 2020-01-09
      • 2014-07-10
      • 2011-03-01
      相关资源
      最近更新 更多