DelegateCommand and EventArgs

Topics: Prism v2 - Silverlight 3
Aug 7, 2009 at 8:32 AM

Hi,

I often need to get EventArgs as CommandParameter of DelegateCommand.

Currenlty I assign it inside custom command behavior. But I think it is very dirty solution because command parameter should be bindable.

What is the best practice to pass eventargs with command.

I'm using Silverlight 3.

Thanks,

Alexey Zakharov.

Aug 7, 2009 at 6:18 PM

Hi Alexey,

I assume you are executing a command when a particular event is taking place. If this is the case you can use commands with attached behaviors. If your behavior inherits from Prism’s CommandBehaviorBase class, you can set the CommandParameter with the event args right before executing the command. You can take the ButtonBaseClickCommandBehavior class that comes with the CAL as an example and do something like:

 

 private void OnClick(object sender, System.Windows.RoutedEventArgs e)

        {

            CommandParameter = e;
ExecuteCommand(); }
You can also check this post that provides another Command with Attached Behavior for the Silverlight 3 DataForm.

Please let me know if this helps.

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

Aug 7, 2009 at 7:12 PM
--->>> CommandParameter = e;

This is what I'm talking about. After this operation u cannot no longer bind CommandParameter. That is why I say that is dirty solution.

I also think that implementing thousands of custom command behavior for each new event you need is bad.

Currently I bind delegate command to my custom triggeraction of Silverlight interaction API. In this case I have no need to implemnt behavior for new events (ex: ListBox SelectedItemChanged etc)

<Button>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click" />
<i:InvokeDelegateCommandAction Command={Binding ...} CommandParameter={Biniding ...} />
</i:EventTrigger />
</i:Interaction.Triggers>
</Button>

Have you look at Expression Interaction API? If you are interested in it. I can share some sources to u.

But in this approach I have still the same problem with setting of EventArgs as commandParameter.
Aug 8, 2009 at 1:32 PM
Edited Aug 8, 2009 at 1:36 PM

I would be interested in more information on the Expression Interaction API!   What steps did you comply with (in Blend) to generate your code?

What about something like the following?

            IDemoPresentationModel model = 
                container.Resolve<IDemoPresentationModel>();

            model.DemoDelegateCommand = 
                new DemoDelegateCommand<EventArgs>(OnDemoExecuted, OnCanExecute);
            
            model.DemoEventArgs = 
                new DemoEventArgs { MyText = "Hello World!" };
        }

        private void OnDemoExecuted(EventArgs e)
        {
            MessageBox.Show(((DemoEventArgs)e).MyText);
        }

        private bool OnCanExecute(EventArgs e)
        {
            DemoEventArgs arg = e as DemoEventArgs;
            if (arg != null)
                arg.MyText += " again!";
            return true;
        }
Where DemoDelegateCommand looks as follows:
using System;
using System.Windows.Input;

namespace Module.Client.Commands
{
    public class DemoDelegateCommand<T> : ICommand
        where T : EventArgs
    {
        public event EventHandler CanExecuteChanged;

        private Action<T> executeMethod;
        private Func<T, bool> canExecuteMethod;

        public DemoDelegateCommand(Action<T> executeMethod, Func<T, bool> canExecuteMethod)
        {
            this.executeMethod = executeMethod;
            this.canExecuteMethod = canExecuteMethod;
        }

        public bool CanExecute(object parameter)
        {
            return canExecuteMethod((T)parameter);
        }

        public void Execute(object parameter)
        {
            executeMethod((T)parameter);
        }
    }
}

With the DataContext set to the Presentation Model the XAML looks as follows:
        <Button Width="100" Height="25" x:Name="DetailsView_ClickMe"
                VerticalAlignment="Top" HorizontalAlignment="Left" 
                Content="Click ME"
                Command="{Binding DemoDelegateCommand}"
                CommandParameter="{Binding DemoEventArgs}"
                />