I think i went somewhat over my head with a little tool i wanted to make.

The idea was to bind certain keys(users choice) to countdown timers and progressbars.
But since the keys are never the same i have to save the chosen key for the selected progressbar.

So when the assigned key is pressed the timer & progressbar linked to that key will start a countdown timer.
But from what i can tell there is no simple way to do this.
Found some examples with keyboard hooks, but none of them where in WPF.

Hope i am making sense about what i want.
And any advice or examples would be much appreciated.

3 Years
Discussion Span
Last Post by Sevyt

You should be able to add the key with the corresponding progressbar to something like a dictionary Dictionary<Char,ProgressBar> and then on keypress check your dictionary and retrieve the relevant entry


Ok, that not know about that.
I am going to look further into that, thanks for the tip.


Use in your main window a Dictionary with a Key and a specific class to store your progress information. Also, have a StackPanel in your main window, to display the ProgressBars.

private Dictionary<Key, Progress> progressBars = 
    new Dictionary<Key, Progress> { 
        { Key.O, new Progress() } , 
        { Key.L, new Progress() } 

Bind your windows KeyDown event, and check for required keys.

private void Window_KeyDown(object sender, KeyEventArgs e)
    if ((e.Key == Key.O  || e.Key == Key.L) && !progressBars[e.Key].isActive)
        progressBars[e.Key].isActive = true;
        progressBars[e.Key].StartProgress(main_stack); //main_stack is a StackPanel

And for your Progress class, you can use something like this:

class Progress
    ProgressBar pb
    bool isActive       // check if the current thread is active
    int time            // a certain amount of seconds for the timer
    BackgroundWorker bw // a thread to run your timer

Also, you'll need to bind the BackgroundWorker's events, such as DoWork, ProgressChanged and RunWorkerCompleted.
Here's my quick take on the Progress class:

class Progress
    public ProgressBar pb = new ProgressBar();
    public Boolean isActive = false;
    public BackgroundWorker bw = new System.ComponentModel.BackgroundWorker();
    public int time = 10;

    public Progress()
        bw.WorkerReportsProgress = true;
        bw.DoWork += bw_DoWork;
        bw.ProgressChanged += bw_ProgressChanged;
        bw.RunWorkerCompleted += bw_RunWorkerCompleted;
        pb.Height = 20;
        pb.MaxWidth = 100;

    void bw_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
        (pb.Parent as StackPanel).Children.Remove(pb); //remove progressBar
        pb.Value = 0;                                  //reset the value
        isActive = false;                              //show it's done

    void bw_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
        this.pb.Value = Math.Min(e.ProgressPercentage, 100);

    void bw_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
        for (int i = 0; i < time; i++)
            bw.ReportProgress((100 * i) / time);

    public void StartProgress(StackPanel grid)

Edited by Lucaci Andrew: Added minor comments


Alright thanks, managed to get it to work with Dictionary.
Also then example helped a lot, thank you very much both of you.

This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.