I saw the light Silverlight Commands Hacks: Passing EventArgs as CommandParameter to DelegateCommand triggered by EventTrigger - Alexey Zakharov's Blog

Silverlight Commands Hacks: Passing EventArgs as CommandParameter to DelegateCommand triggered by EventTrigger

Today I've tried to find a way how to pass EventArgs as CommandParameter to DelegateCommand triggered by EventTrigger. By reverse engineering of default InvokeCommandAction I find that blend team just ignores event args.

To resolve this issue I have created my own action for triggering delegate commands.

public sealed class InvokeDelegateCommandAction : TriggerAction<DependencyObject>
{
    /// <summary>
    ///
    /// </summary>
    public static readonly DependencyProperty CommandParameterProperty =
        DependencyProperty.Register("CommandParameter", typeof(object), typeof(InvokeDelegateCommandAction), null);

    /// <summary>
    ///
    /// </summary>
    public static readonly DependencyProperty CommandProperty = DependencyProperty.Register(
        "Command", typeof(ICommand), typeof(InvokeDelegateCommandAction), null);

    /// <summary>
    ///
    /// </summary>
    public static readonly DependencyProperty InvokeParameterProperty = DependencyProperty.Register(
        "InvokeParameter", typeof(object), typeof(InvokeDelegateCommandAction), null);

    private string commandName;

    /// <summary>
    ///
    /// </summary>
    public object InvokeParameter
    {
        get
        {
            return this.GetValue(InvokeParameterProperty);
        }
        set
        {
            this.SetValue(InvokeParameterProperty, value);
        }
    }

    /// <summary>
    ///
    /// </summary>
    public ICommand Command
    {
        get
        {
            return (ICommand)this.GetValue(CommandProperty);
        }
        set
        {
            this.SetValue(CommandProperty, value);
        }
    }

    /// <summary>
    ///
    /// </summary>
    public string CommandName
    {
        get
        {
            return this.commandName;
        }
        set
        {
            if (this.CommandName != value)
            {
                this.commandName = value;
            }
        }
    }

    /// <summary>
    ///
    /// </summary>
    public object CommandParameter
    {
        get
        {
            return this.GetValue(CommandParameterProperty);
        }
        set
        {
            this.SetValue(CommandParameterProperty, value);
        }
    }

    /// <summary>
    ///
    /// </summary>
    /// <param name="parameter"></param>
    protected override void Invoke(object parameter)
    {
        this.InvokeParameter = parameter;
       
        if (this.AssociatedObject != null)
        {
            ICommand command = this.ResolveCommand();
            if ((command != null) && command.CanExecute(this.CommandParameter))
            {
                command.Execute(this.CommandParameter);
            }
        }
    }

    private ICommand ResolveCommand()
    {
        ICommand command = null;
        if (this.Command != null)
        {
            return this.Command;
        }
        var frameworkElement = this.AssociatedObject as FrameworkElement;
        if (frameworkElement != null)
        {
            object dataContext = frameworkElement.DataContext;
            if (dataContext != null)
            {
                PropertyInfo commandPropertyInfo = dataContext
                    .GetType()
                    .GetProperties(BindingFlags.Public | BindingFlags.Instance)
                    .FirstOrDefault(
                        p =>
                        typeof(ICommand).IsAssignableFrom(p.PropertyType) &&
                        string.Equals(p.Name, this.CommandName, StringComparison.Ordinal)
                    );

                if (commandPropertyInfo != null)
                {
                    command = (ICommand)commandPropertyInfo.GetValue(dataContext, null);
                }
            }
        }
        return command;
    }
}

Example:

<ComboBox>
    <ComboBoxItem Content="Foo option 1" />
    <ComboBoxItem Content="Foo option 2" />
    <ComboBoxItem Content="Foo option 3" />
    <Interactivity:Interaction.Triggers>
        <Interactivity:EventTrigger EventName="SelectionChanged" >
            <Presentation:InvokeDelegateCommandAction
                Command="{Binding SubmitFormCommand}"
                CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=InvokeParameter}" />
        </Interactivity:EventTrigger>
    </Interactivity:Interaction.Triggers>               
</ComboBox>

BTW: InvokeCommanAction CommandName property are trying to find command in properties of view. It very strange, because in MVVM pattern command should be in viewmodel supplied to datacontext.

Published Wednesday, March 24, 2010 12:19 PM by brainbox
Filed under: , , , ,

Comments

# Twitter Trackbacks for Silverlight Commands Hacks: Passing EventArgs as CommandParameter to DelegateCommand triggered by EventTrigger - Alexey Zakharov's Blog [asp.net] on Topsy.com

Pingback from  Twitter Trackbacks for                 Silverlight Commands Hacks: Passing EventArgs as CommandParameter to DelegateCommand triggered by EventTrigger - Alexey Zakharov's Blog         [asp.net]        on Topsy.com

# Links (3/28/2010) &laquo; Steve Pietrek-Everything SharePoint/Silverlight

Pingback from  Links (3/28/2010) &laquo; Steve Pietrek-Everything SharePoint/Silverlight

# ?????? ?? Microsoft Silverlight &raquo; EventArgs ?????? EventTrigger

Pingback from  ?????? ?? Microsoft Silverlight   &raquo; EventArgs ?????? EventTrigger

# re: Silverlight Commands Hacks: Passing EventArgs as CommandParameter to DelegateCommand triggered by EventTrigger

Thursday, June 17, 2010 12:29 AM by VB

Thanks a lot, I was looking for something like this, because I was having some trouble using  InvokeCommandAction with slider:valuechanged event and command-parameter binded to slider.value property. Whenever slider is moved, ICommand function was called in ViewModel properly but problem was command-parameter value was "previous" value not current slider value. This similar thing happens with TextBox control as well.

# re: Silverlight Commands Hacks: Passing EventArgs as CommandParameter to DelegateCommand triggered by EventTrigger

Friday, July 16, 2010 4:19 PM by Nat

Did you ever figure out why the Value is previous when used with Slider? I am seeing the same problem...

Kudos on the article as it was easy to follow and get it working.

# Silverlight 4 MVVM

Monday, August 23, 2010 8:19 PM by Murat Mercan

Silverlight 4 MVVM

# re: Silverlight Commands Hacks: Passing EventArgs as CommandParameter to DelegateCommand triggered by EventTrigger

Tuesday, September 21, 2010 2:23 PM by alphapapalima

I am erroring on :

PropertyInfo commandPropertyInfo = dataContext

                       .GetType()

                       .GetProperties(BindingFlags.Public | BindingFlags.Instance)

                       .FirstOrDefault(

.FirstorDefault seems to be erroring.  I have included System.Reflection.PropertyInfo.  Is this correct?

# re: Silverlight Commands Hacks: Passing EventArgs as CommandParameter to DelegateCommand triggered by EventTrigger

Tuesday, September 21, 2010 2:35 PM by alphapapalima

disregard, I need to include system.linq also.

# re: Silverlight Commands Hacks: Passing EventArgs as CommandParameter to DelegateCommand triggered by EventTrigger

Tuesday, September 21, 2010 3:17 PM by тарас ковтун

Алекс, статья хорошая но ты не мог бы форматировать код попонятней ? а то невозможно читать, в глазах рябит.

# EntityCommandShim<T> – Silverlight MVVM helper

Monday, October 25, 2010 4:15 PM by Rediscovering the Obvious

I received a question yesterday around the shim pattern that I used, and I thought I’d clean it up a

# re: Silverlight Commands Hacks: Passing EventArgs as CommandParameter to DelegateCommand triggered by EventTrigger

Wednesday, June 01, 2011 9:10 AM by phuppe

Hi,

Can you post sample code for your command "SubmitFormCommand" that you have in your example?

Thanks,

Paul

# re: Silverlight Commands Hacks: Passing EventArgs as CommandParameter to DelegateCommand triggered by EventTrigger

Wednesday, June 01, 2011 9:19 AM by phuppe

To be more specific, could you show sample code in the view model where you would declare the command "SubmitFormCommand", set it, and show the method it would call for example.

# re: Silverlight Commands Hacks: Passing EventArgs as CommandParameter to DelegateCommand triggered by EventTrigger

Monday, June 20, 2011 9:47 AM by tigerswithguitars

To be more specific, could you show sample code in the view model where you would declare the command "SubmitFormCommand", set it, and show the method it would call for example. +1

I have wired up this command framework, but my command is always triggering with a NULL object sent back? ViewModel, DelegateCommand problems methinks. But a full example/project/implementation would make a good article amazing!

# CommandParameter of event trigger using InvokeDelegateCommandAction - Programmers Goodies

Pingback from  CommandParameter of event trigger using InvokeDelegateCommandAction - Programmers Goodies

# MVVM Passing EventArgs As Command Parameter - Programmers Goodies

Pingback from  MVVM Passing EventArgs As Command Parameter - Programmers Goodies

# re: Silverlight Commands Hacks: Passing EventArgs as CommandParameter to DelegateCommand triggered by EventTrigger

Monday, October 31, 2011 10:28 AM by frosty

For anybody looking to see what the code is for the Command in the ViewModel.  If you are using MVVM Light's RelayCommand.

You want to pass in the EventArg of the event you are using to trigger the command.  If you aren't sure what this is, then use object, set a break point to figure out what it is.

private RelayCommand<object> _regionTreeViewIsCheckedCommand;

       public RelayCommand<object> RegionTreeViewIsCheckedCommand

       {

           get

           {

               return _regionTreeViewIsCheckedCommand ?? (_regionTreeViewIsCheckedCommand = new RelayCommand<object>((val) =>

               {

                   Debug.WriteLine(val.GetType().ToString();

               }));

           }

       }

# My new command binding approach for WPF &laquo; Blog A. Ziegler

Friday, November 25, 2011 5:46 AM by My new command binding approach for WPF « Blog A. Ziegler

Pingback from  My new command binding approach for WPF &laquo; Blog A. Ziegler

# re: Silverlight Commands Hacks: Passing EventArgs as CommandParameter to DelegateCommand triggered by EventTrigger

Friday, December 23, 2011 1:10 AM by Shenbagaraj

Can u please give example for ComboBox to retrieve the commandParameter value in ViewModel.

# MVVM interaction drop trigger | PHP Developer Resource

Thursday, May 24, 2012 6:23 PM by MVVM interaction drop trigger | PHP Developer Resource

Pingback from  MVVM interaction drop trigger | PHP Developer Resource

Leave a Comment

(required) 
(required) 
(optional)
(required)