【问题标题】:Sharing PropertyChanged data among different viewmodels在不同的视图模型之间共享 PropertyChanged 数据
【发布时间】:2016-03-09 17:34:18
【问题描述】:

MyproblemDescription

如上图所示 ViewModelA 有一个属性 IsPopupOpen。在该属性的更改(值)上,我希望 ViewModelB 和 ViewModelC 应该得到通知。

现在 ViewmodelB 和 ViewModelC 具有属性 IsUserCtlVisible (bool)。 现在我想如果 IsPopupOpen 属性更改(ViewModelA),那么 IsUserCtlVisible 属性应该从 ViewModelA 获取值并获取值。 请帮助我。

【问题讨论】:

    标签: c# .net wpf mvvm


    【解决方案1】:

    有一些选择: 1.使用棱镜,然后在这种情况下使用发布和订阅方法分别触发事件和订阅。 2.如果您不想使用 prism,则使用事件触发并在要订阅事件的另一个视图模型中订阅该事件。 例子: 在第一个视图模型中使用以下代码,这将随着属性 IsPopupOpen 的更改而触发

    public event MyHandler Tick;
            public EventArgs e = null;
            public delegate void MyHandler(ViewModelBase m, EventArgs e);
            MenuItemViewModel menuVM = new MenuItemViewModel();
            UpperWorkstationViewModel UpperVM = new UpperWorkstationViewModel();
            public bool _isPopupOpen = true;
            public virtual bool IsPopupOpen
            {
                get { return _isPopupOpen; }
                set
                {
                    _isPopupOpen = value;
                    OnPropertyChanged("IsPopupOpen");
                    menuVM.Subscribe(this);
                    UpperVM.Subscribe(this);
                    if (Tick != null)
                    { Tick(this, e); }
    
                    //this.SomeEvent.Invoke(IsPopupOpen);                
                }
            }
    

    现在上面的代码将触发事件并订阅事件将以下代码粘贴到任何视图模型中。我已经用 2 个视图模型尝试了这段代码,它适用于 2 个单独的视图模型(MenuItemViewModel 和 UpperWorkstationViewModel)

    public void Subscribe(MainWindowViewModel m)
            {
                m.Tick += new MainWindowViewModel.MyHandler(HeardIt);
            }
            private void HeardIt(ViewModelBase m, EventArgs e)
            {
                if (m != null)
                {
                    if ((bool)(((UI.Viewmodel.MainWindowViewModel)m).IsPopupOpen))
                        IsUpperWSUsrCtlVisible = false;
                    else
                        IsUpperWSUsrCtlVisible = true;
                }
                CommandManager.InvalidateRequerySuggested();
    
                //_dispatcher.BeginInvoke(DispatcherPriority.DataBind,
                //        new DispatcherOperationCallback(ScheduleTransferOperation),
                //        null);
            }
    

    现在运行代码,您会发现该事件将在所有视图模型中触发,您将在其中放置上述代码 sn-p。

    【讨论】:

      【解决方案2】:

      最简单的方法是使用事件。当IsPopupOpen 更改时,它会调用ViewModelBViewModelC 订阅的事件。让此事件传递一个值,以便它可以在您的 IsUserCtlVisible 属性中使用。

      public class ViewModelA
      {  
        public event action<bool> SomeEvent;
          //invoke event somewhere 
          SomeEvent.Invoke(/*some bool argument */)
      }
      
      public class ViewModelB
      {
          public bool IsUserCtlVisible { get; set; }
          public ViewModelB()
          {
              MainViewModel mvm = new MainViewModel();
      
              mvm.SomeEvent += (arg) => { IsUserCtlVisible = arg; };
          }
      }
      

      这只是演示主体的简单方法。您可以使用dependency injectionprism event aggregator 以更简洁的方式执行此操作。

      【讨论】:

      • 如果这些是视图模型,那么它们应该进行属性更改通知,在这种情况下已经有一个事件:PropertyChanged。这就是它的用途!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-20
      相关资源
      最近更新 更多