Saturday, January 7, 2017

InvokeCommandAction passing in EventArgs


using System;
using System.Linq;
    using System.Reflection;
    using System.Windows;
    using System.Windows.Input;
    using System.Windows.Interactivity;

    /// <summary>
    /// For Trigger action Invoke command, Trigger Action will set Invoke Parameter so the foloowing can pass along EventArgs
    ///<i:EventTrigger EventName="MouseLeftButtonDown">
    ///<invokeActions:InvokeDelegateCommandAction>
    ///    <invokeActions:InvokeDelegateCommandAction.CommandParameter>
    ///        <MultiBinding Converter="">
    ///            <Binding/>
    ///            <Binding Path="InvokeParameter" RelativeSource="{RelativeSource Self}" />
    /// </summary>
    public sealed class InvokeDelegateCommandAction : TriggerAction<DependencyObject>
    {
        private string _commandName;

        public static readonly DependencyProperty CommandParameterProperty =
            DependencyProperty.Register("CommandParameter", typeof(object), typeof(InvokeDelegateCommandAction), null);

        public object CommandParameter
        {
            get { return GetValue(CommandParameterProperty);}
            set { SetValue(CommandParameterProperty, value);}
        }

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

        public ICommand Command
        {
            get { return (ICommand)this.GetValue(CommandProperty); }
            set { SetValue(CommandProperty, value);}
        }
 
        public static readonly DependencyProperty InvokeParameterProperty = DependencyProperty.Register(
            "InvokeParameter", typeof(object), typeof(InvokeDelegateCommandAction), null);

        public object InvokeParameter
        {
            get { return GetValue(InvokeParameterProperty); }
            set { SetValue(InvokeParameterProperty, value); }
        }

        public string CommandName
        {
            get
            {
                return _commandName;
            }
            set
            {
                if (CommandName != value)
                {
                    _commandName = value;
                }
            }
        }

        protected override void Invoke(object parameter)
        {
            InvokeParameter = parameter;

            if (AssociatedObject == null)
                return;

            var command = ResolveCommand();
            if ((command != null) && command.CanExecute(CommandParameter))
            {
                command.Execute(CommandParameter);
            }
        }

        private ICommand ResolveCommand()
        {
            ICommand command = null;
            if (Command != null)
            {
                return Command;
            }

            var frameworkElement = AssociatedObject as FrameworkElement;
            if (frameworkElement != null)
            {
                var 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, CommandName, StringComparison.Ordinal)
                        );

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

No comments:

Post a Comment