blah blah blah is here! blah blah » Close

up0down
link

I want to create a window which contains a progress bar and a label. This window will be shown when certain time consuming tasks are performed (upload/download). It should be a modal window in the sense that it is in the foreground and the UI can take no other input until progress reaches 100%. So, how can I implement such a thing in a generic window?

I can create the window easy enough. I can create an event which broadcasts progress. But, how do I make this one window generic enough to act as a progress for several different tasks. How would I intelligently subscribe to the event (say there are 4 different objects with progress events)?

last answered one year ago

1 answers

up0down
link

To make the modal window as generic as possible, I imagine you'd want to customize the ProgressBar from the object which opens it and also to execute the long-running task from that object and update the ProgressBar as necessary.

However, as the window is modal, you can't start the task from the object itself because the ProgressBar will not be rendered until ShowDialog() is called and the window will have been closed when ShowDialog() returns.

That being the case, I would suggest that you pass a delegate to the modal window's constructor containing a reference to the method which will execute the task and that the modal window (Window1 say) uses this delegate to execute the task from its ContentRendered event handler.

Here's a little example I managed to get to work. Although I was opening the modal window from the MainWindow class, it could, of course, be any class.

using System.Threading;
using System.Windows.Threading;

public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}

private ProgressBar progressBar1;

private void button1_Click(object sender, RoutedEventArgs e)
{
Window1 w1 = new Window1(Process);
progressBar1 = w1.progressBar1;
progressBar1.Minimum = 0;
progressBar1.Maximum = 100;
w1.ShowDialog();
}

// the task to be executed
private void Process()
{
double value = 0;
do
{
Thread.Sleep(250);
value++;
// copy 'value' to a new variable to avoid capture
// by the anonymous method
double temp = value;
Dispatcher.Invoke(DispatcherPriority.Background,
(SendOrPostCallback)delegate { progressBar1.SetValue(ProgressBar.ValueProperty, temp); }, null);
}
while (value < progressBar1.Maximum);
}
}

public partial class Window1 : Window
{
private Action process;

public Window1(Action process)
{
this.process = process;
InitializeComponent();
}

// add from designer
private void Window_ContentRendered(object sender, EventArgs e)
{
process(); // fire delegate
}

}

Feedback