C#:在搜索/计算过程中禁用按钮

时间:2015-09-09 13:15:58

标签: c# wpf mvvm

我有一个搜索对话框,我想在搜索过程中禁用搜索按钮。这是当前代码,但按钮未取消激活

查看:

<Button Content="Search" 
        Command="{Binding StartSearchCommand}" 
        IsEnabled="{Binding IsNotSearching}" />

视图模型:

private bool _isNotSearching;
public bool IsNotSearching
{
    get { return _isNotSearching; }
    set
    {
        _isNotSearching = value;
        OnPropertyChanged("IsNotSearching");
    }
}


private RelayCommand<object> _startSearchCommand;
public ICommand StartSearchCommand
{
    get
    {
        if (_startSearchCommand == null)
            _startSearchCommand = new RelayCommand<object>(p => ExecuteSearch());
        return _startSearchCommand;
    }
}
private void ExecuteSearch()
{
    IsNotSearching = false;
    //do some searching here
    IsNotSearching = true;
}

4 个答案:

答案 0 :(得分:7)

我因为这个原因(基于着名的DelegateCommand)创建了AsyncDelegateCommand,它在执行命令操作期间在内部禁用命令(在UI中):

public class AsyncDelegateCommand : ICommand
{
    readonly Action<object> _execute;
    readonly Predicate<object> _canExecute;
    bool _running;

    public event EventHandler CanExecuteChanged;

    public AsyncDelegateCommand(Action<object> execute, Predicate<object> canExecute = null)
    {
        _execute = execute;
        _canExecute = canExecute;
    }

    public bool CanExecute(object parameter)
    {
        return (_canExecute == null ? true : _canExecute(parameter)) && !_running;
    }

    public async void Execute(object parameter)
    {
        _running = true;
        Update();
        await Task.Run(() => _execute(parameter));
        _running = false;
        Update();
    }

    public void Update()
    {
        if (CanExecuteChanged != null)
            CanExecuteChanged(this, EventArgs.Empty);
    }
}

XAML:

<Button Command="{Binding SomeCommand}" .../>

视图模型:

AsyncDelegateCommand SomeCommand { get; }

    // in constructor
    SomeCommand = new AsyncDelegateCommand(o =>  { Thread.Sleep(5000); }); // code to run

答案 1 :(得分:0)

我不确定点击和禁用时的外观 - 它可能看起来相同。

但是netaholic是正确的。如果在主UI线程中执行逻辑,则UI可能会冻结,直到执行结束(并且不会更改或更改为快速)。

尝试将您的逻辑放在dispatcher中。就像代码的下一部分一样。

Application.Current.Dispatcher.BeginInvoke(
  DispatcherPriority.Background,
  new Action(() => { 
    //do some searching here
  }));

BTW,我接受了这段代码there

编辑:请勿将此用于您的解决方案。这是错误的(检查评论)。

需要更新可视元素异步时使用调度程序。

Application.Current.Dispatcher.BeginInvoke(
      DispatcherPriority.Background,
      new Action(() => { 
        textbox.Content = "some result";
      }));

答案 2 :(得分:0)

你可以试试命令可以执行以禁用命令而不添加IsEnabled属性

private RelayCommand _startSearchCommand;
    public RelayCommand StartSearchCommand
    {
        get
        {
            return _startSearchCommand??
                   (_startSearchCommand=
                //Added can execute command , only execute if system is not busy at the moment.
                       new RelayCommand(async () => await OnExecuteSearch(), () => !IsBusy));
        }

    }

命令处理程序

internal async Task OnExecuteSearch()
    {
        IsBusy = true;

        //Execute your action
        //and finally
        IsBusy = false;

    }

的Xaml

 <Button Command="{Binding StartSearchCommand}">

中继命令中的canexecute将为您控制IsEnabled属性。

答案 3 :(得分:0)

此代码必须有效。

private async void ExecuteSearch() {
        IsNotSearching = false;

        var task = Task.Factory.StartNew(() => {
            //do some searching here
        });
        await task;

        IsNotSearching = true;
    }