我的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然后将被调用。我怎样才能确保每次调用它们。
答案 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
}
}