2017-04-19 94 views
0

我在我的WPF应用程序下面的代码,我用它来启用或我的UI禁用按钮WPF CanExecute不会被调用每次

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。我如何确保每次都调用这些函数。

+0

你可以发布_currentValue全属性代码? – Krishna

+0

你有什么理由为什么你使用这些类型的命令?通常他们会进入你的'ViewModel'?我使用自己的'ICommand'实现,它允许我处理何时调用'可以执行改变'。这里是[链接到这样的实现](http://stackoverflow.com/a/22286816/2029607) – XAMlMAX

+1

类似的事情发生在我身上。尝试在执行命令后在代码隐藏中调用'CommandManager.InvalidateRequerySuggested()'。 http://stackoverflow.com/questions/2331622/weird-problem-where-button-does-not-get-re-enabled-unless-the-mouse-is-clicked – MickyD

回答

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 
    } 
} 
+0

CommandOne.RaiseCanExecuteChanged();给出错误错误\t CS1061 \t“RoutedUICommand”不包含关于“RaiseCanExecuteChanged”的定义和没有扩展方法“RaiseCanExecuteChanged”接受类型为“RoutedUICommand”可以发现第一个参数(是否缺少using指令或程序集引用?) –

+1

@HarryBoy我的错误RoutedUICommand没有内置的RaiseCanExecuteChanged我认为你需要使用InvalidateRequerySuggested – Krishna

2

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

什么,但是你应该做的是实现自己的命令 - 这是一个实现了ICommand接口的类 - 每当你想获得名为CanExecute方法提高CanExecuteChanged事件的命令的。

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

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

内置RoutedUICommand类有没有这样的方法,我很害怕。