relaycommand传递参数wpf

时间:2018-09-26 18:16:04

标签: wpf mvvm parameter-passing relaycommand

我要做的就是将参数从xaml传递到视图模型中。为了启用执行操作的按钮,我的命令无法执行CanExecuteChanged事件。

如果没有参数传递到视图模型中,则执行此逻辑没有问题。

我认为需要在我的Relaycommand类中进行一些更改。有人可以帮我正确配置吗?我已经查看了此类问题的答案,但是仍然无法启用Delete按钮才能执行DeleteThanks方法。

在RelayCommand类的ICommand.CanExecute方法中,_TargetCanExecuteMethod和_TargetExecuteMethod始终为null。因此,请不要在视图模型中执行CanDeleteThanks方法。

请注意,由于Delete命令的签名,因此需要在同一个命名类中插入第二个RelayCommand方法。但是,该方法内部的那些对象未在ICommand.CanExecute方法中实现。

这是我的xaml:

<Button x:Name="btnDelete"
                    Content="Delete"
                    Command="{Binding DeleteThanksCommand}"
                    CommandParameter="{Binding Text, ElementName=Subject}"
                    IsEnabled="{Binding DeleteEnabled}"
                    HorizontalAlignment="Left"
                    Grid.Row="0"
                    Grid.Column="0" Foreground="#FF0C1334">
            </Button>

这是我的视图模型:

public GiveThanksViewModel()
        {
            DeleteThanksCommand = new RelayCommand(param => DeleteThanks(param), param => CanDeleteThanks(param));
        }

private bool _DeleteEnabled;
        public bool DeleteEnabled
        {
            get
            {
                return _DeleteEnabled;
            }
            set
            {
                if (_DeleteEnabled != value)
                {
                    _DeleteEnabled = value;
                }
            }
        }

public RelayCommand DeleteThanksCommand { get; private set; }

private void DeleteThanks(object action)
        {
            try
            {
                ...
                    DeleteEnabled = false;
                    DeleteThanksCommand.RaiseCanExecuteChanged();
                }
            }
            catch (Exception ex)
            {
                messageService.ShowNotification(ex.Message);
            }
        }

        private bool CanDeleteThanks(object parameter)
        {
            return DeleteEnabled;
        }

这是Relaycommand类:

public class RelayCommand : ICommand
    {
        Action _TargetExecuteMethod;
        Func<bool> _TargetCanExecuteMethod;
        private Action<object> action;
        private Func<object, bool> canDeleteThanks;

        public RelayCommand(Action executeMethod, Func<bool> canExecuteMethod)
        {
            _TargetExecuteMethod = executeMethod;
            _TargetCanExecuteMethod = canExecuteMethod;
        }

        public RelayCommand(Action<object> action, Func<object, bool> canDeleteThanks)
        {
            this.action = action;
            this.canDeleteThanks = canDeleteThanks;
        }

        public void RaiseCanExecuteChanged()
        {
            CanExecuteChanged(this, EventArgs.Empty);
        }
        #region ICommand Members

        bool ICommand.CanExecute(object parameter)
        {
            if (_TargetCanExecuteMethod != null)
            {
                return _TargetCanExecuteMethod();
            }
            if (_TargetExecuteMethod != null)
            {
                return true;
            }
            return false;
        }

        // Beware - should use weak references if command instance lifetime is longer than lifetime of UI objects that get hooked up to command
        // Prism commands solve this in their implementation
        public event EventHandler CanExecuteChanged = delegate { };

        void ICommand.Execute(object parameter)
        {
            if (_TargetExecuteMethod != null)
            {
                _TargetExecuteMethod();
            }
        }
        #endregion
    }

这是同一RelayCommand类中的另一半代码,在调试时永远不会执行。我认为由于我的参数,下面的代码需要执行。

public class RelayCommand<T> : ICommand
    {
        Action<T> _TargetExecuteMethod;
        Func<T, bool> _TargetCanExecuteMethod;

        public RelayCommand(Action<T> executeMethod, Func<T,bool> canExecuteMethod)
        {
            _TargetExecuteMethod = executeMethod;
            _TargetCanExecuteMethod = canExecuteMethod;
        }

        public void RaiseCanExecuteChanged() 
        {
             CanExecuteChanged(this, EventArgs.Empty); 
        }
        #region ICommand Members

        bool ICommand.CanExecute(object parameter)
        {
            if (_TargetCanExecuteMethod != null)
            {
                T tparm = (T)parameter;
                return _TargetCanExecuteMethod(tparm);
            }
            if (_TargetExecuteMethod != null)
            {
                return true;
            }
            return false;
        }

        // Beware - should use weak references if command instance lifetime is longer than lifetime of UI objects that get hooked up to command
        // Prism commands solve this in their implementation
        public event EventHandler CanExecuteChanged = delegate { };

        void ICommand.Execute(object parameter)
        {
            if (_TargetExecuteMethod != null)
            {
                _TargetExecuteMethod((T)parameter);
            }
        }
        #endregion
    }

1 个答案:

答案 0 :(得分:0)

我通过修改以下内容使其起作用:

在ViewModel中,我从原始代码更改为以下内容:

DeleteThanksCommand = new RelayCommand<object>((parms) => DeleteThanks(parms), parms => CanDeleteThanks());

public RelayCommand<object> DeleteThanksCommand { get; private set; }