TriggerAction擴展----ExInvokeCommandAction

  Wp&Win8中使用命令綁定時,除了Button控件自帶命令綁定,其他的時候是用Interactivity庫中的InvokeCommandAction實現的(Win8 需要額外安裝第三方NuGet包纔可使用,我的MVFM示例博客中帶有這個庫),但使用過程中發現InvokeCommandAction並不能滿足我們的要求,主要有以下幾點:
  1 無法獲取發送者;
  2 用EventTrigger觸發時往往需要用到EventArg參數,但是InvokeCommandAction無法獲取;
  3 有時需要傳遞多個參數,無法滿足;
  於是我對InvokeCommandAction進行了一些改進,首先定義參數的結構體:
    /// <summary>  
    /// 擴展CommandParameter,使CommandParameter可以帶事件參數  
    /// </summary>  
    public class ExCommandParameter
    {
        /// <summary>  
        /// 事件觸發源  
        /// </summary>  
        public object Sender { get; set; }
        /// <summary>  
        /// 事件參數  
        /// </summary>  
        public object EventArgs { get; set; }
        /// <summary>  
        /// 參數  
        /// </summary>  
        public object Parameter { get; set; }
        /// <summary>  
        /// 擴展參數  
        /// </summary>  
        public object Parameter2 { get; set; }
        /// <summary>  
        /// 擴展參數  
        /// </summary>  
        public object Parameter3 { get; set; }
    }  
  然後定義處理的TriggerAction:
 /// <summary>  
    /// 擴展的InvokeCommandAction  
    /// </summary>  
    public class ExInvokeCommandAction : CustomTriggerActionBase
    {
        private string commandName;
        public static readonly DependencyProperty CommandProperty = DependencyProperty.Register("Command", typeof(ICommand), typeof(ExInvokeCommandAction), null);
        public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register("CommandParameter", typeof(object), typeof(ExInvokeCommandAction), null);
        public static readonly DependencyProperty CommandParameter2Property = DependencyProperty.Register("CommandParameter2", typeof(object), typeof(ExInvokeCommandAction), null);
        public static readonly DependencyProperty CommandParameter3Property = DependencyProperty.Register("CommandParameter3", typeof(object), typeof(ExInvokeCommandAction), null);

        /// <summary>  
        /// 獲得或設置此操作應調用的命令的名稱。  
        /// </summary>  
        /// <value>此操作應調用的命令的名稱。</value>  
        /// <remarks>如果設置了此屬性和 Command 屬性,則此屬性將被後者所取代。</remarks>  
        public string CommandName
        {
            get
            {
                return this.commandName;
            }
            set
            {
                if (this.commandName != value)
                {
                    this.commandName = value;
                }
            }
        }
   
        /// <summary>  
        /// 獲取或設置此操作應調用的命令。這是依賴屬性。  
        /// </summary>  
        /// <value>要執行的命令。</value>  
        /// <remarks>如果設置了此屬性和 CommandName 屬性,則此屬性將優先於後者。</remarks>  
        public ICommand Command
        {
            get
            {
                return (ICommand)base.GetValue(ExInvokeCommandAction.CommandProperty);
            }
            set
            {
                base.SetValue(ExInvokeCommandAction.CommandProperty, value);
            }
        }
        /// <summary>  
        /// 獲得或設置命令參數。這是依賴屬性。  
        /// </summary>  
        /// <value>命令參數。</value>  
        /// <remarks>這是傳遞給 ICommand.CanExecute 和 ICommand.Execute 的值。</remarks>  
        public object CommandParameter
        {
            get
            {
                return base.GetValue(ExInvokeCommandAction.CommandParameterProperty);
            }
            set
            {
                base.SetValue(ExInvokeCommandAction.CommandParameterProperty, value);
            }
        }

        public object CommandParameter2
        {
            get
            {
                return base.GetValue(ExInvokeCommandAction.CommandParameter2Property);
            }
            set
            {
                base.SetValue(ExInvokeCommandAction.CommandParameter2Property, value);
            }
        }

        public object CommandParameter3
        {
            get
            {
                return base.GetValue(ExInvokeCommandAction.CommandParameter3Property);
            }
            set
            {
                base.SetValue(ExInvokeCommandAction.CommandParameter3Property, value);
            }
        }

        /// <summary>  
        /// 調用操作。  
        /// </summary>  
        /// <param name="parameter">操作的參數。如果操作不需要參數,則可以將參數設置爲空引用。</param>  
        protected override void Invoke(object parameter)
        {
            ICommand command = this.ResolveCommand();

            ExCommandParameter exParameter = new ExCommandParameter
            {
                Sender = this.AssociatedObject,
                Parameter = GetValue(CommandParameterProperty),
                Parameter2 = GetValue(CommandParameter2Property),
                Parameter3 = GetValue(CommandParameter3Property),
                EventArgs = parameter

            };

            if (command != null && command.CanExecute(exParameter))
            {
                command.Execute(exParameter);
            }
        }

        //手動觸發
        public void TriggerCommand()
        {
            Invoke(null);
        }

        public void TriggerCommand(object CommandParameter)
        {
            TriggerCommand(null, CommandParameter);
        }

        public void TriggerCommand(object sender = null, object commandParameter = null, object commandParameter2 = null, object commandParameter3 = null)
        {
            this.CommandParameter = commandParameter;
            this.CommandParameter2 = commandParameter2;
            this.CommandParameter3 = commandParameter3;
            Invoke(null);
        }

        protected ICommand ResolveCommand()
        {
            ICommand result = null;
            if (this.Command != null)
            {
                result = this.Command;
            }
            else
            {
                foreach (PropertyInfo propertyInfo in this.AssociatedObject.GetType().GetTypeInfo().DeclaredProperties)
                {
                    if (typeof(ICommand).GetTypeInfo().IsAssignableFrom(propertyInfo.PropertyType.GetTypeInfo()) && string.Equals(propertyInfo.Name, this.CommandName, StringComparison.Ordinal))
                    {
                        result = (ICommand)propertyInfo.GetValue((object)this.AssociatedObject, (object[])null);
                    }
                }
            }
            return result;
        }
    }
  使用時和InvokeCommandAction是一樣的:
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Loaded">  
             <Behavior:ExInvokeCommandAction Command="{Binding Command,Source={StaticResource ViewModel}}" CommandParameter="1" CommandParameter2="2" CommandParameter3="3"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章