C#: Disable button during search/calculation

前端 未结 4 1062
梦如初夏
梦如初夏 2021-01-16 12:58

I have a search dialog where I want to disable the search button during the search. This is the current code but the button does not get deactivated

View:

         


        
相关标签:
4条回答
  • 2021-01-16 13:20

    You could try command can execute to disable the command without adding IsEnabled property

    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));
            }
    
        }
    

    Command handler

    internal async Task OnExecuteSearch()
        {
            IsBusy = true;
    
            //Execute your action
            //and finally
            IsBusy = false;
    
        }
    

    Xaml

     <Button Command="{Binding StartSearchCommand}">
    

    The canexecute in the Relay Command will control the IsEnabled property for you.

    0 讨论(0)
  • 2021-01-16 13:27

    I am not sure about looks when it was clicked and disabled - it is possible that it looks same.

    But netaholic is right. If you execute logic in main UI thread it is possible that UI is frozen till your execution end (and isn't changed or changed to fast).

    Try to put your logic in dispatcher. Like in next part of the code.

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

    BTW, I took this code there.

    EDIT: don't use this for your solution. This is wrong (check comments).

    Use dispatcher when you need to update visual element async.

    Application.Current.Dispatcher.BeginInvoke(
          DispatcherPriority.Background,
          new Action(() => { 
            textbox.Content = "some result";
          }));
    
    0 讨论(0)
  • 2021-01-16 13:42

    I've made an AsyncDelegateCommand for that reason (based on famous DelegateCommand), it internally disable command (in UI) during executing command action:

    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}" .../>
    

    ViewModel:

    AsyncDelegateCommand SomeCommand { get; }
    
        // in constructor
        SomeCommand = new AsyncDelegateCommand(o =>  { Thread.Sleep(5000); }); // code to run
    
    0 讨论(0)
  • 2021-01-16 13:45

    This code must work.

    private async void ExecuteSearch() {
            IsNotSearching = false;
    
            var task = Task.Factory.StartNew(() => {
                //do some searching here
            });
            await task;
    
            IsNotSearching = true;
        }
    
    0 讨论(0)
提交回复
热议问题