我有一个按钮,单击它以启动任务并禁用按钮,当任务完成时,我想启用此按钮。请给我任何想法,概念或代码,以便我理解。
我的代码如下:
在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
}
答案 0 :(得分:2)
这是第一个非常天真的方法,没有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)
}
如果您有一个不能等待的长期任务,您可以按Task.Run
运行它,如下所示:
private async Task RunTask()
{
await Task.Run(() =>
{
// do somthing here
});
}
答案 1 :(得分:-1)
以下是 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();
}
}