Running command in other module

Topics: Prism v2 - WPF 3.5
Mar 26, 2009 at 8:35 AM
Hi.

I wonder whether there are guidelines for running commands defined in other modules. Imagine we have module A with a command called CommandA. CommandA is executing code in module A. Then we have module B, who also would like to use CommandA. How would we go about implementing the relationship between the two modules when they shouldn't know each others existance?

I was hoping there was some structure similar to composite event aggregating, but CompositeCommand (with the register/unregister functionality) seems more adapted to bundling multiple commands, not solve the issue I'm having.

Best regards,
Mattias
Mar 26, 2009 at 7:04 PM

Hi Mattias,

 

In this scenario, a viable approach could be making CommandA available globally (for multiple modules). There is a topic in the Composite Application Guidance for WPF & Silverlight, that explains how to get this done:

·         How to: Create Globally Available Commands

 

If you would like more details about commands, and when to use each of the different possible combinations with them, you could check the following topics in the Prism-v2 documentation:

·         Commands

·         Communication

·         How to: Create Locally Available Commands

 

Another good alternative would be to register the command in the container using a string key to differentiate between commands:

    container.RegisterInstance<ICommand>("Module1Command",myCommand); //Container is an instance of the Unity Container

 

Then you can get the same command in another module like this:

    ICommand module1Command = container.Resolve<ICommand>("Module1Command");

 

Once you have an instance of the command you will be able to bind it to a control of your choosing.

 

The approach you decide to take, if it is one of the above or not, depends on your specific application’s needs.

 

Please let me know if this helps.

 

Damian Schenkelman

http://blogs.southworks.net/dschenkelman

Mar 27, 2009 at 3:00 PM
The first solution where you have a global CompositeCommand was the thing I was after. Just wasn't sure CompositeCommands was designed to work like that.

Thanks for the quick feedback!

Best regards,
Mattias
Oct 16, 2009 at 1:23 AM

I have been having this problem for several days.  I have a view that has a has a button.  I want the the code to handle the button enable and execute to be in viewmodel that is not the viewmodel where the contrl is.  I am using the CompositeCommand can not seem to get things wired up correctly. 

namespace Test_Commanding_Binding
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();

            ViewModel vm = new ViewModel();

            vm.changeCount();

            vm.changeCount();

            vm.changeCount();

            vm.changeCount();
        }
    }
}

<Window x:Class="Test_Commanding_Binding.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:View="clr-namespace:Test_Commanding_Binding.View"
    Title="Window1" Height="300" Width="300">
    <Grid>
<View:RibbionView />
    </Grid>
</Window>

using Microsoft.Practices.Composite.Presentation.Commands;

namespace Infrastructure
{
    public static class Commands
    {
        public static CompositeCommand Save = new CompositeCommand(true);
    }
}

using System.Windows.Forms;
using System.Windows.Input;
using Infrastructure;
using Microsoft.Practices.Composite.Presentation.Commands;

namespace Test_Commanding_Binding
{
    public class ViewModel
    {
        protected ICommand _saveCommand;
        private int _count;

        public ViewModel()
        {
            _saveCommand = new DelegateCommand<object>(parm => SaveEntity(), parm => IsDirty());
            Commands.Save.RegisterCommand(_saveCommand);
        }


        private bool IsDirty()
        {
            return _count > 3;

           
        }

        private object SaveEntity()
        {
            return MessageBox.Show("Hello");
        }

        public void changeCount()
        {
            _count++;
            _saveCommand.CanExecute(this);
        }
    }

}

Please help me understand

Oct 16, 2009 at 9:35 PM

Hi,

Assuming you are trying to bind the button to the command in code behind, one thing to note is that the DataContext of the view that contains the button must be set to the ViewModel that has the command (you can check the Commanding Quickstart for more information about that). How are you setting the DataContext of the RibbonView?

Could you provide a small repro sample that illustrates the full scenario?

In the meantime the following documents might provide more information:

Please let me know if this helps.

Damian Schenkelman
http://blogs.southworks.net/dschenkelman