WPF使用成熟的命令系统(带参数)

前文不需要带参数的成熟命令:
WPF使用成熟的命令系统


需要的五个类如下所示:
在这里插入图片描述

定义分别如下所示:

IExecuteWithObject 接口:

public interface IExecuteWithObject
{
    object Target { get; }
    void ExecuteWithObject(object parameter);
    void MarkForDeletion();
}

IExecuteWithObjectAndResult 接口:

public interface IExecuteWithObjectAndResult
{
    object ExecuteWithObject(object parameter);
}

RelayCommand< T > 类:

public class RelayCommand<T> : ICommand
{
    private readonly WeakAction<T> _execute;

    private readonly WeakFunc<T, bool> _canExecute;

    public RelayCommand(Action<T> execute, bool keepTargetAlive = false) : this(execute, null, keepTargetAlive) { }

    public RelayCommand(Action<T> execute, Func<T, bool> canExecute, bool keepTargetAlive = false)
    {
        if (execute == null)
        {
            throw new ArgumentNullException("execute");
        }

        _execute = new WeakAction<T>(execute, keepTargetAlive);

        if (canExecute != null)
        {
            _canExecute = new WeakFunc<T, bool>(canExecute, keepTargetAlive);
        }
    }

    public event EventHandler CanExecuteChanged
    {
        add { if (_canExecute != null) { CommandManager.RequerySuggested += value; } }

        remove { if (_canExecute != null) { CommandManager.RequerySuggested -= value; } }
    }

    public void RaiseCanExecuteChanged() { CommandManager.InvalidateRequerySuggested(); }

    public bool CanExecute(object parameter)
    {
        if (_canExecute == null)
        {
            return true;
        }

        if (_canExecute.IsStatic || _canExecute.IsAlive)
        {
            if (parameter == null && typeof(T).IsValueType) { return _canExecute.Execute(default(T)); }

            if (parameter == null || parameter is T) { return (_canExecute.Execute((T)parameter)); }
        }

        return false;
    }

    public virtual void Execute(object parameter)
    {
        var val = parameter;

        if (parameter != null && parameter.GetType() != typeof(T))
        { if (parameter is IConvertible) { val = Convert.ChangeType(parameter, typeof(T), null); } }


        if (CanExecute(val) && _execute != null && (_execute.IsStatic || _execute.IsAlive))
        {
            if (val == null)
            {
                if (typeof(T).IsValueType) { _execute.Execute(default(T)); }
                else { _execute.Execute((T)val); }
            }
            else { _execute.Execute((T)val); }
        }
    }
}

WeakAction< T > 类:

public class WeakAction<T> : WeakAction, IExecuteWithObject
{
    private Action<T> _staticAction;

    public override string MethodName
    {
        get
        {
            if (_staticAction != null)
            {
                return _staticAction.Method.Name;
            }

            return Method.Name;
        }
    }

    public override bool IsAlive
    {
        get
        {
            if (_staticAction == null && Reference == null) { return false; }

            if (_staticAction != null)
            {
                if (Reference != null) { return Reference.IsAlive; }

                return true;
            }

            return Reference.IsAlive;
        }
    }

    public WeakAction(Action<T> action, bool keepTargetAlive = false)
        : this(action == null ? null : action.Target, action, keepTargetAlive) { }

    public WeakAction(object target, Action<T> action, bool keepTargetAlive = false)
    {
        if (action.Method.IsStatic)
        {
            _staticAction = action;

            if (target != null) { Reference = new WeakReference(target); }

            return;
        }
        Method = action.Method;
        ActionReference = new WeakReference(action.Target);
        LiveReference = keepTargetAlive ? action.Target : null;
        Reference = new WeakReference(target);

        if (ActionReference != null && ActionReference.Target != null && !keepTargetAlive)
        {
            var type = ActionReference.Target.GetType();

            if (type.Name.StartsWith("<>") && type.Name.Contains("DisplayClass"))
            {
                System.Diagnostics.Debug.WriteLine(
                    "You are attempting to register a lambda with a closure without using keepTargetAlive. Are you sure? Check http://galasoft.ch/s/mvvmweakaction for more info.");
            }
        }
    }

    public new void Execute() { Execute(default(T)); }

    public void Execute(T parameter)
    {
        if (_staticAction != null)
        {
            _staticAction(parameter);
            return;
        }

        var actionTarget = ActionTarget;

        if (IsAlive)
        {
            if (Method != null && (LiveReference != null || ActionReference != null) && actionTarget != null)
            {
                Method.Invoke(actionTarget, new object[] { parameter });
            }
        }
    }

    public void ExecuteWithObject(object parameter)
    {
        var parameterCasted = (T)parameter;
        Execute(parameterCasted);
    }

    public new void MarkForDeletion()
    {
        _staticAction = null;
        base.MarkForDeletion();
    }
}

WeakFunc< T > 类:

public class WeakFunc<T, TResult> : WeakFunc<TResult>, IExecuteWithObjectAndResult
{
    private Func<T, TResult> _staticFunc;

    public override string MethodName
    {
        get
        {
            if (_staticFunc != null) { return _staticFunc.Method.Name; }

            return Method.Name;
        }
    }

    public override bool IsAlive
    {
        get
        {
            if (_staticFunc == null && Reference == null) { return false; }

            if (_staticFunc != null) { if (Reference != null) { return Reference.IsAlive; } return true; }

            return Reference.IsAlive;
        }
    }

    public WeakFunc(Func<T, TResult> func, bool keepTargetAlive = false)
        : this(func == null ? null : func.Target, func, keepTargetAlive) { }

    public WeakFunc(object target, Func<T, TResult> func, bool keepTargetAlive = false)
    {
        if (func.Method.IsStatic)
        {
            _staticFunc = func;

            if (target != null)
            {
                Reference = new WeakReference(target);
            }

            return;
        }

        Method = func.Method;
        FuncReference = new WeakReference(func.Target);

        LiveReference = keepTargetAlive ? func.Target : null;
        Reference = new WeakReference(target);

        if (FuncReference != null && FuncReference.Target != null && !keepTargetAlive)
        {
            var type = FuncReference.Target.GetType();

            if (type.Name.StartsWith("<>")
                && type.Name.Contains("DisplayClass"))
            {
                System.Diagnostics.Debug.WriteLine(
                    "You are attempting to register a lambda with a closure without using keepTargetAlive. Are you sure? Check http://galasoft.ch/s/mvvmweakaction for more info.");
            }
        }
    }

    public new TResult Execute() { return Execute(default(T)); }

    public TResult Execute(T parameter)
    {
        if (_staticFunc != null)
        {
            return _staticFunc(parameter);
        }

        var funcTarget = FuncTarget;

        if (IsAlive)
        {
            if (Method != null && (LiveReference != null || FuncReference != null) && funcTarget != null)
            {
                return (TResult)Method.Invoke(funcTarget, new object[] { parameter });
            }

        }

        return default(TResult);
    }

    public object ExecuteWithObject(object parameter)
    {
        var parameterCasted = (T)parameter;
        return Execute(parameterCasted);
    }

    public new void MarkForDeletion()
    {
        _staticFunc = null;
        base.MarkForDeletion();
    }
}

假如我们需要访问Bing这个网页进行搜索,我需要一个参数,可以这样定义,如下所示:
实例命令:
在这里插入图片描述
方法如下所示:
在这里插入图片描述
这个 obj 就是我们传入的参数(TextBox类型,需要其中的SelectedText属性),XAML绑定情况如下所示:
1)快捷键:
在这里插入图片描述
菜单绑定:
在这里插入图片描述
现在执行这个命令就可以跳转到网页了,并且搜索指定的内容,如下所示:

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_42100963/article/details/107589968