0

I have a button in a grid and I want it to be disabled after 5 sec. I have tried to do that by a Timer's Elapsed event and Enabled property. Here is my button -

<Window.DataContext>
    <local:VM/>
</Window.DataContext>
<Grid>
    <Button Content="Button" Command="{Binding ACommand}"/>
</Grid>

and I have tried with following code -

public class VM
{
    Timer timer;
    public Command ACommand { get; set; }
    public VM()
    {
        timer = new Timer(5000);
        timer.Start();
        timer.Elapsed += disableTimer;
        ACommand = new Command(Do, CanDo);
    }

    bool CanDo(object obj) => timer.Enabled;
    void Do(object obj) { }

    void disableTimer(object sender, ElapsedEventArgs e)
    {
        timer.Stop();
        timer.Enabled = false;
    }
}

It remains enabled after 5 sec.

1 Answers1

0

You need to raise the CanExecuteChanged event of your command. I don't know how your "Command" class is implemented but it should have a public method for raising this event:

public class Command : System.Windows.Input.ICommand
{
    private readonly Predicate<object> _canExecute;
    private readonly Action<object> _execute;

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

    public bool CanExecute(object parameter)
    {
        if (_canExecute == null)
            return true;

        return _canExecute(parameter);
    }

    public void Execute(object parameter)
    {
        _execute(parameter);
    }

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

You will then need to call this method whenever you want to refresh the state of the command, i.e. whenever you want the CanDo delegate to get invoked again. Make sure that you raise the event on the UI thread:

void disableTimer(object sender, ElapsedEventArgs e)
{
    timer.Stop();
    timer.Enabled = false;
    Application.Current.Dispatcher.Invoke(new Action(() => ACommand.RaiseCanExecuteChanged()));
}
mm8
  • 163,881
  • 10
  • 57
  • 88