0

I have a scenario that Main-window has content control i switch user control of particular view through it and have View-Models respectively

In one of my User-Control has another user-control in it. Both have a View-Model

<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>  

I want Notify the View-model 1 Collection when View-model 2 Collection is Changed

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

What i'm trying to achieve when my collection inside View-model 2 is updated i want to notify in View-model 1.

Eldho
  • 7,795
  • 5
  • 40
  • 77
  • Design your view models differently, something along the lines of: Create a another/new view model, which will provide you with viewmodel1 and viewmodel2. Use that view model for your user control. Inside that view model you can then take care of registering event handlers for ObservableCollection events –  Apr 22 '14 at 13:13
  • Thanks @elgonzo can we use Messenger-Service to Viewmodel2 => Viewmodel 1 and Raise the property there ? ReceiveAction ( OnCollectionChanged(new NotifyCollectionChanged) ) – Eldho Apr 22 '14 at 13:17
  • Perhaps you can, but why would you want to do it for such a simple thing? It would just make your code more complicated and debugging more difficult. (Perhaps, your real scenario is much more complex than the sample in your question. But then i would be even less suited to provide any opinion because of my complete lack of understanding your situation.) –  Apr 22 '14 at 13:21

1 Answers1

2

When using MVVM, I like to use just one view model to one view. If you simply take your inner UserControl to be part of its parent UserControl, then you'll only need one view model. Try re-arranging your code like this:

<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> 

In this way, you just have to manage the one collection in the one view model and most of your problems will just disappear.

Sheridan
  • 68,826
  • 24
  • 143
  • 183
  • Thanks @Sheridan , its was also my option . But my View-model 1 is bit heavy so i want a clean code that why i keep it Two Vm's. Is there any other approach of doing this. – Eldho Apr 22 '14 at 13:58
  • Firstly, there is nothing wrong with having a large view model. Secondly, *this is* the easy option. If you *really* want to pass values from one view model to another, you can use `delegate`s to do that. See my answers to the [Passing parameters between viewmodels](http://stackoverflow.com/questions/19513555/passing-parameters-between-viewmodels/19514713#19514713) and [How to call functions in a main view model from other view models?](http://stackoverflow.com/questions/19522202/how-to-call-functions-in-a-main-view-model-from-other-view-models/19522419#19522419) for further help with that. – Sheridan Apr 22 '14 at 14:04
  • Thanks @Sheridan , reference are really helpful, and am going to follow your approach. – Eldho Apr 22 '14 at 14:15