如何在任务完成时启用WPF中的按钮
我有一个按钮,点击它启动任务并禁用按钮,当任务完成时,我想启用此按钮。请给我任何想法,概念或代码,以便我理解。如何在任务完成时启用WPF中的按钮
我的代码如下:
在XAML:
<Button Name="myButton" Content="START" Click="ButtonStartClick" />
在xaml.cs:
private void ButtonStartClick(object sender, RoutedEventArgs e)
{
RunTask();
myButton.IsEnabled = false;
}
在viewModel.cs:
private void OnTaskCompleted(string result)
{
//how to enable myButton
}
这里是一个第一种非常幼稚的方法,没有MVVM
private async void ButtonStartClick(object sender, RoutedEventArgs e)
{
myButton.IsEnabled = false;
await RunTask();
myButton.IsEnabled = true;
}
其中RunTask声明如下:
private async Task RunTask()
{
// await some other awaitable method(s)
}
如果你有一个长期运行的任务,是不是awaitable,您可以通过Task.Run
像这样运行:
private async Task RunTask()
{
await Task.Run(() =>
{
// do somthing here
});
}
这是正确的答案,因为他正在使用代码隐藏点击事件。但我同意,还有其他方式通过绑定来实现这一点;主要用于MVVM模式。 –
只是为了说清楚,使用视图模型并不意味着您不能使用async/await。异步RunTask方法也可以驻留在视图模型中。 – Clemens
@clemens thons完成 – Coding4Fun
这里是一个解决方案,在MVVM风格的。 MainWindowViewModel.IsButtonEnabled定义按钮是否可以被用户点击。 ICommand.CanExecute定义命令是否在点击时触发。
Window.xaml:
<Window>
<Grid>
<Button Content="Click me!" Command="{Binding ButtonCmd}" IsEnabled="{Binding IsButtonEnabled}" Width="100" Height="30"/>
</Grid>
</Window>
Window.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new MainWindowViewModel();
}
}
ViewModel.cs
class MainWindowViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private bool _isButtonEnabled = true;
private ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
public MainWindowViewModel()
{
ButtonCmd = new Command(OnButtonClick,() => IsButtonEnabled);
}
public ICommand ButtonCmd { get; private set; }
public bool IsButtonEnabled
{
get
{
_lock.EnterReadLock();
bool result = _isButtonEnabled;
_lock.ExitReadLock();
return result;
}
set
{
_lock.EnterWriteLock();
_isButtonEnabled = value;
_lock.ExitWriteLock();
OnPropertychanged(nameof(IsButtonEnabled));
}
}
private void OnButtonClick()
{
Task.Factory.StartNew(()=>{
IsButtonEnabled = false;
Thread.Sleep(1000);
IsButtonEnabled = true;
});
}
private void OnPropertychanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
Command.cs
class Command : ICommand
{
public event EventHandler CanExecuteChanged;
Action _cmd;
Func<bool> _canExecute;
public Command(Action cmd, Func<bool> canExecute)
{
_cmd = cmd;
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return _canExecute();
}
public void Execute(object parameter)
{
_cmd();
}
}
向我们展示'RunTask'的代码。你不应该先禁用按钮**吗? – MickyD