9

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

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; }
4

4 回答 4

15

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

我花了大约一天的时间来找出我的申请到底出了什么问题。我希望这会对你们中的一些人有所帮助。

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

于 2015-10-15T13:29:55.413 回答
6

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

public RelayCommand RedoCommand{
     get;
     set;
}

您也可以在设置可选之前设置私有,具体取决于您的访问级别。然后你做

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

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

于 2013-10-22T08:28:20.020 回答
1

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

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

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

于 2013-10-14T16:09:21.730 回答
1

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

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

编辑

由于您使用的是 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();
    }
于 2013-10-14T16:09:30.117 回答