wpf MVVM RelayCommand CanExecute

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19364364/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 09:51:14  来源:igfitidea点击:

MVVM RelayCommand CanExecute

wpfwindows-phone-8mvvm-lightrelaycommandcanexecute

提问by JonasN89

I'm implementing an RelayCommand with an execute and an canExecute part. The RelayCommand works when it is without the canExecute part, however when I add the canExecute part, the command locks the button. The RelayCommand only checks whether or not the button can be executed as long as the CanExecute part is true. Once the canExecute part becomes false, the button can no longer be clicked, even if it is supposed to. How do I make sure that every time I click on the button it controls whether or not it can be executed, and doesn't lock it forever, once it cannot be executed?

我正在实现一个带有 execute 和 canExecute 部分的 RelayCommand。RelayCommand 在没有 canExecute 部分时工作,但是当我添加 canExecute 部分时,命令会锁定按钮。RelayCommand 只检查按钮是否可以执行,只要 CanExecute 部分为真。一旦 canExecute 部分变为 false,则无法再单击该按钮,即使它应该单击。如何确保每次单击按钮时它都会控制它是否可以执行,并且一旦无法执行就不会永远锁定它?

RedoCommand = new RelayCommand(undoRedoController.Redo,undoRedoController.CanRedo);

   public bool CanRedo()
    {
        redoStack.Count();
        redoStack.Any();
        return redoStack.Any();
    }

    public void Redo()
    {
        if (redoStack.Count() <= 0) throw new InvalidOperationException();
        IUndoRedoCommand command = redoStack.Pop();
        undoStack.Push(command);
        command.Execute();
    }


 public class UndoRedoController
{
    private static UndoRedoController controller = new UndoRedoController();

    private readonly Stack<IUndoRedoCommand> undoStack = new Stack<IUndoRedoCommand>();
    private readonly Stack<IUndoRedoCommand> redoStack = new Stack<IUndoRedoCommand>();

    private UndoRedoController() { }

    public static UndoRedoController GetInstance() { return controller; }

采纳答案by JTIM

For some reason you have to do the following:

出于某种原因,您必须执行以下操作:

public RelayCommand RedoCommand{
     get;
     set;
}

you can also put private before set optional, depending on your access level. Then you do

根据您的访问级别,您还可以在设置为可选之前设置私有。然后你做

RedoCommand = new RelayCommand(() => undoRedoController.Redo(), () => undoRedoController.CanRedo());

Now your able to call RedoCommand.RaiseCanExecuteChanged(); And everything works.

现在您可以调用 RedoCommand.RaiseCanExecuteChanged(); 一切正常。

回答by SSX-SL33PY

There has been a hiatus with MVVMLight due to the fact that after the .NET 4.5 update the CommandManager no longer fires the can execute check. This has since been solved. Instead of including the GalaSoft.MvvmLight.Command namespace you should use the GalaSoft.MvvmLight.CommandWpf namespace. The RelayCommand defined in that namespace is still checking the CanExecute function that you pass to the command.

由于 .NET 4.5 更新后 CommandManager 不再触发可执行检查,MVVMLight 出现了中断。这已经被解决了。您应该使用 GalaSoft.MvvmLight.CommandWpf 命名空间,而不是包含 GalaSoft.MvvmLight.Command 命名空间。在该命名空间中定义的 RelayCommand 仍在检查您传递给命令的 CanExecute 函数。

Took me about a day to find out what the hell was going wrong in my application. I hope this will help some of you.

我花了大约一天的时间才找出我的应用程序到底出了什么问题。我希望这会帮助你们中的一些人。

Hereis a blog post by the developer explanining why this is necessary.

是开发人员的一篇博客文章,解释了为什么这是必要的。

回答by Aron

If you are using an unpatched .net 4.5. Microsoft broke the .CanExecuteevent.

如果您使用的是未打补丁的 .net 4.5。微软打破了这一.CanExecute事件。

http://connect.microsoft.com/VisualStudio/feedback/details/753666/net-4-0-application-commands-canexecute-not-updating-in-4-5

http://connect.microsoft.com/VisualStudio/feedback/details/753666/net-4-0-application-commands-canexecute-not-updating-in-4-5

If you are using the RelayCommandfrom http://msdn.microsoft.com/en-us/magazine/dd419663.aspx#id0090030and are not raising the CanExecuteChanged event when redoStack changes.

如果您使用RelayCommand来自http://msdn.microsoft.com/en-us/magazine/dd419663.aspx#id0090030并且在重做堆栈更改时未引发 CanExecuteChanged 事件。

回答by tsiorn

(Answering from a Silverlight perspective so assuming this will help you.)

(从 Silverlight 的角度回答,因此假设这会对您有所帮助。)

Are you doing a RedoCommand.RaiseCanExecuteChanged()anywhere? Once whatever condition you are monitoring changes, you'll need to raise this command manually.

你在RedoCommand.RaiseCanExecuteChanged()任何地方做吗?一旦您监视的任何条件发生变化,您都需要手动发出此命令。

EDIT

编辑

Since you are using MVVM Light.. Heres sample code:

由于您使用的是 MVVM Light .. 下面是示例代码:

RedoCommand = new RelayCommand(undoRedoController.Redo,undoRedoController.CanRedo);

   public bool CanRedo()
    {
        redoStack.Count();
        redoStack.Any();
        return redoStack.Any();
    }

    public void Redo()
    {
        if (redoStack.Count() <= 0) throw new InvalidOperationException();
        IUndoRedoCommand command = redoStack.Pop();
        undoStack.Push(command);
        command.Execute();

        // At this point, your stacks have changed; that is, the stacks
        // may or may not contain items. Thus, raise the commands CanExecute part
        // which will in turn enable/disable the commands based on the functions
        // return value

        RedoCommand.RaiseCanExecuteChanged();

        // assuming you could possibly have an UndoCommand somewhere
        UndoCommand.RaiseCanExecuteChanged();
    }