Commanding between Usercontrols

Topics: Questions
Sep 29, 2012 at 9:25 PM


I have a usercontrol (special-searchbox) which can be placed on many places.
For example on another usercontrol containing the searchbox and a results-viewer.

Now I need a way to inform the parent usercontrol about a new search to be executed.
If it was a button, I would bind to the Command of the button.
Yes, I know it could be done by Messaging between the two VMs, but I would like to know if I could get it to work similar to the Buttons commanding.

The problem ist, when I implement ICommandSource on the searchbox-view, how can I execute this command from the searchbox-viewmodel?
Similar when I implement an event on the view, I cannot raise it from the viewmodel...

I would like to do something like following:

    <SearchControl ExecuteSearchCommand="{Binding xyz}" />
any ideas?

thanks, alex.
Oct 1, 2012 at 6:42 AM

You replied in another thread:

"The [Commanding between Usercontrols] thread is solved using the same technique.
In fact I use messaging with individual Tag values provided by the master control to the child via ViewToViewModel binding.
Using <SearchControl ExecuteMessageTag="{Binding}" /> the controls ViewModel has a reference to the parent's ViewModel.
This reference is passed as Tag with the Message. The parent only accepts Messages with (this) as tag. Everyone is happy :-)"

However, you might also be interested in the InterestedIn attribute. It provides memory leak free auto subscriptions to view models. If you pass the UniqueIdentifier of a view model as tag, it is easy to get the right property changes and executed commands from other view models.

Oct 3, 2012 at 9:51 AM

Hi Geert,

I have the following problems with your tip using InterestedIn.

My ViewModel is based on Catel.MVVM.IViewModel only.
This interface does not expose a OnViewModelCommandExecuted method.

With "pass the UniqueIdentifier of a viewmodel as tag", do you mean the following?
  cmd = new Command<string>(ExecuteSearch, tag: this.UniqueIdentifier);

From the example in 2), the ExecuteSearch method is within the source viewmodel.
I want it to be in the viewmodel which is InterestedIn the source vm.
But if it is not in the source VM, how can I create the new Command then?

Until now, the ExecuteSearch() method collects parameters, builds a message with them
and send them via the message mediator.
When I change this to use the InterestedIn method, how can I pass the parameters
along with the command?
The element which executes the command is not aware about the parameters at all.

Do I have to create a second command which in executed within the ExecuteSearch() method?

I am a litte bit confused...

Oct 3, 2012 at 9:55 AM

1) Implement INotifyableViewModel as well

2) yes, that is the tag you need to pass. Then you know which VM did it. You can also check the viewModel.UniqueIdentifier in the OnViewModelCommandExecuted

3) You have to pass in your context somehow to the command. For example, by setting it as datacontext.

4) If you use specific parameters which are required, then keep using the messenger. I thought you were just interested in whether the command was executed.