WPF MVVM AsyncCommand CanExecute not working



我正在尝试创建一个简单的WPF应用程序,该应用程序具有一个填充有服务器名称的组合框和一个连接到服务器的按钮。

预期行为:按钮最初被禁用,但一旦选择服务器,按钮就会可用。

我使用的AsyncCommand在这篇实现异步任务的ICommand方法的博客文章中发现了这一点。

我的问题是,当使用普通的RelayCommand时,该按钮工作正常,但当我使用AsynCommand时不工作。我是不是错过了什么?

这是简化的代码:

ConnectionWindow.xaml.cs:

<ComboBox Grid.Row="1" Grid.Column="1" 
HorizontalAlignment="Left"
x:Name="listSourceServer" 
ItemsSource="{Binding ListSourceServer}" 
SelectedValue="{Binding SelectedSourceServer}" 
VerticalAlignment="Top" 
Width="450"        
RenderTransformOrigin="0.5,0.5"/>
<Button Grid.Row="1" Grid.Column="2"
Content="Connect"
HorizontalAlignment="Left" 
VerticalAlignment="Top"
Width="100"
Height="25"
FontFamily="Arial"
Foreground="#FFFFFF"
Background="#2e86de"
Command="{Binding ButtonConnectSourceServer}">
</Button>

ConnectionViewModel.cs:

private string _selectedSourceServer;
public string SelectedSourceServer
{
set
{
_selectedSourceServer = value;
OnPropertyChanged(nameof(SelectedSourceServer));
}
get => _selectedSourceServer;
}
private async Task ConnectSourceServerAsync()
{
await ConnectAsync(SelectedSourceServer);
}
private bool CanConnectOnSourceServer()
{
return !string.IsNullOrEmpty(SelectedSourceServer);
}
public ConnectionViewModel() { 
ButtonConnectSourceServer = new AsyncCommand(ConnectSourceServerAsync, CanConnectOnSourceServer);
}

AsyncCommand.cs:

public interface IAsyncCommand : ICommand
{
Task ExecuteAsync();
bool CanExecute();
}
public class AsyncCommand : IAsyncCommand
{
public event EventHandler CanExecuteChanged;
private bool _isExecuting;
private readonly Func<Task> _execute;
private readonly Func<bool> _canExecute;
private readonly IErrorHandler _errorHandler;
public AsyncCommand(
Func<Task> execute,
Func<bool> canExecute = null,
IErrorHandler errorHandler = null)
{
_execute = execute;
_canExecute = canExecute;
_errorHandler = errorHandler;
}
public bool CanExecute()
{
return !_isExecuting && (_canExecute?.Invoke() ?? true);
}
public async Task ExecuteAsync()
{
if (CanExecute())
{
try
{
_isExecuting = true;
await _execute();
}
finally
{
_isExecuting = false;
}
}
RaiseCanExecuteChanged();
}
public void RaiseCanExecuteChanged()
{
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}
#region Explicit implementations
bool ICommand.CanExecute(object parameter)
{
return CanExecute();
}
void ICommand.Execute(object parameter)
{
ExecuteAsync().FireAndForgetSafeAsync(_errorHandler);
}
#endregion
}

SelectedSourceServer属性更改时,需要调用RaiseCanExecuteChanged方法。

public ConnectionViewModel()
{
_buttonConnectSourceServer = new AsyncCommand(ConnectSourceServerAsync, CanConnectOnSourceServer);
}
private readonly AsyncCommand _buttonConnectSourceServer;
public IAsyncCommand ButtonConnectSourceServer => _buttonConnectSourceServer;
private string _selectedSourceServer;
public string SelectedSourceServer
{
get => _selectedSourceServer;
set
{
_selectedSourceServer = value;
OnPropertyChanged(nameof(SelectedSourceServer));
_buttonConnectSourceServer.RaiseCanExecuteChanged();
}
}

相关内容

  • 没有找到相关文章

最新更新