Reputation: 611
I have a ViewModel that holds an ObservableCollection. This collection is getting updated all the time. Now I want to share this ObservableCollection with another ViewModel.
VM1
public Class VM1
{
private ObservableCollection<CameraPackage> _cameraPackagesPerScenes = new ObservableCollection<CameraPackage>();
public ObservableCollection<CameraPackage> CameraPackagesPerScenes
{
get { return _cameraPackagesPerScenes; }
set { _cameraPackagesPerScenes = value; RaisePropertyChanged(); }
}
public VM1
{
var SCFunctions = new SharedCollectionLayer();
SCFunctions.AddToCameraPackagesPerSceneAndPartials(CameraPackagesPerScene);
}
}
Now I want to use the same ObservableCollection in VM2. How do I do this? I already tried to create a new class that holds the ObservableCollection I achieve to get the data in the Collection but When I try to get it from the other VM it becomes null.
public class SharedCollectionLayer
{
private ObservableCollection<CameraPackage> _cameraPackagesPerScenes = new ObservableCollection<CameraPackage>();
public ObservableCollection<CameraPackage> CameraPackagesPerScenes
get { return _cameraPackagesPerScenes ; }
set { _cameraPackagesPerScenes = value; RaisePropertyChanged(); }
}
}
public ObservableCollection<CameraPackage> GetCameraPackagesPerSceneAndPartials()
{
var CameraPackagesPerScene = new ObservableCollection<CameraPackage>();
foreach (CameraPackage camerapackage in CameraPackagesPerSceneAndPartials)
{
CameraPackagesPerScene.Add(camerapackage);
}
return CameraPackagesPerScene;
}
public void AddToCameraPackages(ObservableCollection<CameraPackage> CameraPackagesPerScene)
{
foreach(CameraPackage camerapackage in CameraPackagesPerScene)
{
CameraPackagesPerSceneAndPartials.Add(camerapackage);
}
}
}
And in VM2 I'm trying to get the items in the observableCollection but it returns empty.
VM2
public Class VM2
{
private ObservableCollection<CameraPackage> _cameraPackagesPerScene = new ObservableCollection<CameraPackage>();
public ObservableCollection<CameraPackage> CameraPackagesPerScene
{
get { return _cameraPackagesPerScene; }
set { _cameraPackagesPerScene = value; RaisePropertyChanged(); }
}
public VM
{
var SCFunctions = new SharedCollectionLayer();
CameraPackagesPerScene = SCFunctions.GetCameraPackagesPerSceneAndPartials();
}
}
I'm very new to WPF and MVVM, so What is the right approach of sharing ObservableCollections between ViewModels?
Upvotes: 1
Views: 1554
Reputation: 544
Based on the information, here is what is wrong In both of your view models you are creating new objects of SharedCollectionLayer. So both of them have different instances and hence you are not getting the values from VM1 to VM2
Solution
The way to solve this problem is to have a single object shared between both of the view models. You can either follow a singleton pattern below, or a factory pattern where the factory decides what model to give to a view model
Make your SharedCollectionLayer a singleton and then reference it in both the view models.
So you would have something like this
public class SharedCollectionLayerSingleton
{
private static SharedCollectionLayerSingleton instance
public static SharedCollectionLayerSingleton Instance
{
if(instance == null)
{
instance = new SharedCollectionLayerSingleton()
}
return instance;
}
private SharedCollectionLayerSingleton()
{
// initialize here
}
}
In the factory method, you can basically have a factory create a model or return the same model based on certain conditions. Do not have view models as the conditions but state of your application as the condition.
I do not know how your collection is changing so I cannot really comment what is a better way. Regardless of which pattern you follow make sure to keep the observable collection in the same object as long as you want views of both viewmodels reflecting the change simultaneously.
Hope this helps
Upvotes: 2