每次都不会调用WPF CanExecute

时间:2017-04-19 08:33:33

标签: c# wpf

我的WPF应用程序中有以下代码,用于启用或禁用我的UI上的按钮

XAML

<Button x:Name="FirstButton" Command="{x:Static local:MyClass.CommandOne}"/>
<Button x:Name="FirstButton" Command="{x:Static local:MyClass.CommandTwo}"/>

代码背后

CommandBindings.Add(new CommandBinding(CommandOne, CommandOne_Executed, CommandOne_CanExecute));
CommandBindings.Add(new CommandBinding(CommandTwo, CommandTwo_Executed, CommandTwo_CanExecute));

public static readonly RoutedUICommand CommandOne = new RoutedUICommand();
public static readonly RoutedUICommand CommandTwo = new RoutedUICommand();

private void CommandOne_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
    if (e != null)
        e.CanExecute = (_currentValue > 1);
}

private void CommandTwo_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
    if (e != null)
        e.CanExecute = (_currentValue > 100);
}

工人代码

private async Task DoSomeWork(int value)
{
    await Task.Run(() =>
    {
        // Do some work on value
        _currentValue = value
    }
}

我发现当_currentValue的值由于某些处理而发生变化时,有时会调用CommandOne_CanExecute和CommandTwo_CanExecute函数。如果我那么,例如移动UI然后将被调用。我怎样才能确保每次调用它们。

2 个答案:

答案 0 :(得分:2)

您可以调用CommandManager.InvalidateRequerySuggested()方法使所有命令无效。

然而,你应该做的是实现你自己的命令 - 它只是一个实现ICommand接口的类 - 并且只要你想要CanExecuteChanged就引发命令的CanExecute事件。调用方法。

或者您可以使用任何MVVM框架中包含的ICommand的任何实现。例如,您可以查看MvvmLight中RelayCommand类的实现方式:https://github.com/paulcbetts/mvvmlight/blob/master/GalaSoft.MvvmLight/GalaSoft.MvvmLight%20(NET35)/Command/RelayCommand.cs

它有一个RaiseCanExecuteChanged()方法,您可以调用该方法来引发命令的CanExecuteChanged事件。这将导致调用CanExecute方法并使命令失效。

内置的RoutedUICommand类恐怕没有这样的方法。

答案 1 :(得分:0)

您需要为CurrentValue而不是变量和raisecanexecutechanged事件创建属性 请尝试下面的代码

    private int _currentValue = false;
    public bool CurrentValue
    {
        get { return _currentValue; }
        set 
          { 
              if(_currentValue != value)
                CommandManager.InvalidateRequerySuggested();
              SetProperty(ref _currentValue, value); 

          }
    }

CommandBindings.Add(new CommandBinding(CommandOne, CommandOne_Executed, CommandOne_CanExecute));
CommandBindings.Add(new CommandBinding(CommandTwo, CommandTwo_Executed, CommandTwo_CanExecute));

public static readonly RoutedUICommand CommandOne = new RoutedUICommand();
public static readonly RoutedUICommand CommandTwo = new RoutedUICommand();

private void CommandOne_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
    if (e != null)
        e.CanExecute = (CurrentValue > 1);
}

private void CommandTwo_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
    if (e != null)
        e.CanExecute = (CurrentValue > 100);
}

private async Task DoSomeWork(int value)
{
    await Task.Run(() =>
    {
        // Do some work on value
        CurrentValue = value
    }
}