如何在任务完成时启用WPF中的按钮

时间:2017-06-15 02:32:52

标签: c# wpf xaml

我有一个按钮,单击它以启动任务并禁用按钮,当任务完成时,我想启用此按钮。请给我任何想法,概念或代码,以便我理解。

我的代码如下:

在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
     }

2 个答案:

答案 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();
    }
}