我正在嘗試創建一個簡單的 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);
}
異步命令.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
}
uj5u.com熱心網友回復:
您需要在屬性更改RaiseCanExecuteChanged時呼叫該方法。SelectedSourceServer
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();
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/426003.html
下一篇:WPF將視窗標題系結到復選框狀態
