Reference to viewmodel

Mar 9, 2012 at 8:00 AM

Hello

How do i get a reference to the viewmodel in code when the viewmodel is automatical generated in the view?

Coordinator
Mar 9, 2012 at 8:19 AM

The ViewModel property. If you don't use the UserControl base class, it's behavior.ViewModel

Mar 9, 2012 at 8:28 AM

Yes, for sure. But then i need a referece to the view. And mvvm is not designed for hold a reference from view in the viewmodel.

Coordinator
Mar 9, 2012 at 9:49 AM
Edited Mar 9, 2012 at 10:33 AM

Then what do you want to achieve? If you are in a view, you can always access the vm. Or do you want to het vm x in vm y? If so, why? There are several options:

  1. InterestedInAttribute
  2. MessageMediator
  3. ParentViewModel
Mar 12, 2012 at 11:08 AM

Ok. I needed a ChildViewModel :-). So i try it with the InterestedInAttribute. Thanks.

Mar 19, 2012 at 10:52 AM

In a method in Viewmodel i want to set a property in a childviwmodel. With InterestedInAttribute i have to set a property in the viewmodel. And in the childviewmodel i can react in the OnViewModelPropertyChanged method. But i have a list of childviewmodels. So i need also a list of propertys in ViewModel.

Or is in this case the MessageMediator the better way?

Coordinator
Mar 19, 2012 at 10:59 AM

Then it is better to use the mediator. You should think of why you want to control a child view model from a parent view model. By default, it is better to create a loose coupled solution. For example, you broadcast a message (using the message mediator) and the child view models can respond to this. Another way is to create a property, but a property for the sake of sending a message is not good, then you can better use the message mediator.

Mar 19, 2012 at 11:20 AM

Ok. So i have to wait for the other answer in the nested viemodel discussion.

Example

House
   -  Room (List)
       - Part (List)
            - Furniture (List) (Binding Combobox )
               - ActiveFurniture (Property)  (Binding Combobox SelectedItem)

 

HouseViewModel is interested in an other ViewModel. So the OnViewModelPropertyChanged  method in the HousViewModel is called. And now i want to show an special Furniture in the Combobox. So i want to set the ActiveFurniture in every Room/Part.

Coordinator
Mar 19, 2012 at 11:23 AM

Yes, indeed. I usually write a service that keeps track of such a thing. For example, if you want to keep track of a selected item in a applicaiton, I write a service that holds the selected item, and a change notification. Each interested class can subscribe to events (if you want with the WeakEventListener). Then everytime one class sets a value, it updates the value on the service and all other classes are aware of this change.

The message mediator is a "shortcut", but I think writing a real service is a cleaner solution.

Mar 19, 2012 at 12:25 PM

Ok is there a example for Service? For an easier access.

Coordinator
Mar 19, 2012 at 12:34 PM

No, but it is something like this:

public interface ISelectionService : INotifyPropertyChanged
{
	object SelectedObject { get; set; }
}

public class SelectionService : ObservableObject, ISelectionService
{
    private object _selectedObject;
	
	public object SelectedObject
	{
		get { return _selectedObject; }
		set
		{
			_selectedObject = value;
			RaisePropertyChanged(() => SelectedObject);
		}
	}
}

 don't forget to register it in the IoC container:

ServiceLocator.Instance.RegisterType<ISelectionService, SelectionService>();

Mar 19, 2012 at 12:42 PM

Ok i try to unterstand.

So the ViewModel implements ISelectionService and  the other viewmodels reacts on the PropertyChanged event. Right?

Coordinator
Mar 19, 2012 at 12:47 PM

No, the SelectionService is a separate service. In MVVM, you have Models, ViewModels and Models. Besides that, you have lots of services that assist and that you can register for each app. For example, the PleaseWaitService, MessageService, etc.

In your view models, you should query this:

var selectionService = GetService<ISelectionService>();

Then you can set or get the values ,and subscribe to events if you want.

Mar 19, 2012 at 2:04 PM

Oh. Sorry but at the moment thats not clear for me.

I don't know how to say every child viewmodel that its selected index have to change.

Mar 20, 2012 at 12:16 PM
Edited Mar 20, 2012 at 12:16 PM

Hello again:

In

ServiceLocator.Instance.RegisterType<ISelectionService, SelectionService>(); 

the Symbol "Instance" is not known. I included

using Catel.IoC;

What is wrong?

Coordinator
Mar 20, 2012 at 12:41 PM

Interesting, should work. Maybe the ServiceLocator is already an instance (for example, a ViewModelBase class already has a ServiceLocator property which internall calls ServiceLocator.Instance to make it easier for you).