【问题标题】:relaycommand pass parameter wpfrelaycommand 传递参数 wpf
【发布时间】:2019-03-02 14:18:13
【问题描述】:

我要做的就是将参数从 xaml 传递到视图模型。 CanExecuteChanged 事件未针对我的命令触发以启用执行操作的按钮。

如果没有参数传入视图模型,我执行这个逻辑没有问题。

我认为我的 Relaycommand 类需要更改一些内容。有人可以帮我正确配置吗?我已查看此类问题的答案,但仍然无法启用删除按钮以执行 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
    }

【问题讨论】:

  • 您没有重新创建这些骨架类,而是查看过 MVVM Light 吗?它可以做您想做的事情,而且非常稳定且维护良好。

标签: wpf mvvm parameter-passing relaycommand


【解决方案1】:

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

在 ViewModel 中,我将原来的代码改成如下:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-27
    • 1970-01-01
    • 2018-12-25
    • 2012-01-06
    • 2014-06-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多