【问题标题】:Notify Collection changed across viewmodels通知集合跨视图模型更改
【发布时间】:2014-04-22 12:58:07
【问题描述】:

我有一个场景,主窗口具有内容控制,我通过它切换特定视图的用户控制并分别具有视图模型

在我的一个用户控件中有另一个用户控件。两者都有一个视图模型

<UserControl DataContext="ViewModel1">

<Grid>

 <ListView ItemsSource="{Binding TimeSlotCollection}"  <!--This Collection is in ViewModel 1-->
                  ">
  </ListView>

  <UserControl DataContext="ViewModel2">
      <DataGrid x:Name="DataGrid" 
              CanUserAddRows="True"                 
              ItemsSource="{Binding TimeSlotCollection,Mode=TwoWay,
              UpdateSourceTrigger=PropertyChanged}"/>  <!--This Collection is in ViewModel 2-->
 </Grid>

</UserControl>  

我想在视图模型 2 集合发生更改时通知视图模型 1 集合

MyViewModel 1

    private ObservableCollection<AttendanceTimeSlotModel> _timeslotCollection;

    public ObservableCollection<AttendanceTimeSlotModel> TimeSlotCollection
    {
        get { return _timeslotCollection; }
        set
        {
            Set(TimeSlotCollectionPropertyName, ref _timeslotCollection, value);
        }
    }



    public const string EmployeesCollectionPropertyName = "Employees";

    private ObservableCollection<EmployeeModel> _employees;

    public ObservableCollection<EmployeeModel> Employees
    {
        get { return _employees; }
        set
        {
            Set(EmployeesCollectionPropertyName, ref _employees, value);
        }
    }


    public const string IsBusyPropertyName = "IsBusy";

    private bool _isBusy = false;
    public bool IsBusy
    {
        get
        {
            return _isBusy;
        }
        set
        {
            Set(IsBusyPropertyName, ref _isBusy, value);
        }
    }

MyViewModel 2

    public const string AttendanceTimeSlotCollectionPropertyName = "TimeSlotCollection";

    private ObservableCollection<AttendanceTimeSlotModel> _timeSlotCollection = null;

    public ObservableCollection<AttendanceTimeSlotModel> TimeSlotCollection
    {
        get
        {
            return _timeSlotCollection;
        }
        set
        {
            Set(AttendanceTimeSlotCollectionPropertyName, ref _timeSlotCollection, value);
        }
    } 

    /// What i trying 
     public void AddNewTimeSlot(AttendanceTimeSlotModel timeSlot)
    {


        _designdataService.InsertTimeSlot(timeSlot);
        var Vm = SimpleIoc.Default.GetInstance<ViewModels.AssignTimeSlotViewModel>();
        RaisePropertyChanged(Vm.TimeSlotCollection);
    }

当我在 View-model 2 中的集合更新时我想要在 View-model 1 中通知我想要实现的目标。

【问题讨论】:

  • 以不同的方式设计您的视图模型,大致如下: 创建另一个/新的视图模型,它将为您提供 viewmodel1 和 viewmodel2。将该视图模型用于您的用户控件。在该视图模型中,您可以为 ObservableCollection 事件注册事件处理程序
  • 谢谢@elgonzo 我们可以使用 Messenger-Service 到 Viewmodel2 => Viewmodel 1 并在那里提高财产吗? ReceiveAction ( OnCollectionChanged(new NotifyCollectionChanged) )
  • 也许你可以,但你为什么要为了这么简单的事情去做呢?它只会使您的代码更加复杂,调试更加困难。 (也许,您的实际情况比您问题中的示例复杂得多。但是由于我完全不了解您的情况,因此我更不适合提供任何意见。)

标签: c# wpf mvvm mvvm-light


【解决方案1】:

在使用 MVVM 时,我喜欢只对一个视图使用一个视图模型。如果您只是将您的内部UserControl 视为其父UserControl 的一部分,那么您只需要一个视图模型。尝试像这样重新排列您的代码:

<UserControl DataContext="ViewModel1">
    <Grid>    
        <ListView ItemsSource="{Binding TimeSlotCollection}" />
        <UserControl DataContext="{Binding TimeSlotCollection}">
            ... 
            <!-- Then inside the inner control -->
            <DataGrid x:Name="DataGrid" ItemsSource="{Binding}" ... />
            ...
        </UserControl>
    </Grid>
</UserControl> 

这样,您只需要在一个视图模型中管理一个集合,大部分问题就会消失。

【讨论】:

  • 谢谢@Sheridan,这也是我的选择。但是我的 View-model 1 有点重,所以我想要一个干净的代码,为什么我保留它两个 Vm。有没有其他方法可以做到这一点。
  • 首先,拥有大视图模型并没有错。其次,这是简单的选择。如果您真的想将值从一个视图模型传递到另一个视图模型,您可以使用delegates 来做到这一点。请参阅我对 Passing parameters between viewmodelsHow to call functions in a main view model from other view models? 的回答以获得更多帮助。
  • 谢谢@Sheridan,参考真的很有帮助,我会按照你的方法。
猜你喜欢
  • 1970-01-01
  • 2012-11-14
  • 1970-01-01
  • 2010-11-28
  • 2014-10-06
  • 2023-04-02
  • 2014-05-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多