tags:

views:

234

answers:

2

I have a WPF app, upon clicking a button, the app goes into a calculation that can take 4-10 seconds. I'd like to update the opacity of the background and show a progress bar, during that operation.

To do that, I use this code:

this.Cursor = System.Windows.Input.Cursors.Wait;

// grey-out the main window
SolidColorBrush brush1 = new SolidColorBrush(Colors.Black);
brush1.Opacity = 0.65;
b1 = LogicalTreeHelper.FindLogicalNode(this, "border1") as Border;
b1.Opacity = 0.7;
b1.Background = brush1;

// long running computation happens here .... 
// show a modal dialog to confirm results here
// restore background and opacity here. 

When I run the code, the background and opacity doesn't change until the modal dialog appears. How can I get those visual changes to happen right now, before the calculation begins? In Windows Forms there was an Update() method on each control, that did this as necessary, as I recall. What's the WPF analog?

A: 

What if you would do long running computation in the background thread? Once they are done dispatch results back to UI thread...

Honestly, I suspect there is nothing else there, that can solve your problem. Maybe nested pumping will do the trick, but I really doubt it.

Just in case this reference is helpful: Build More Responsive Apps With The Dispatcher

Anvaka
I've tried quite a few things since posting. doing the computation in a BackgroundWorker also did not help. I sometimes get what I want using a DispatcherFrame as described in one of the responses to this thread (http://social.msdn.microsoft.com/forums/en-US/wpf/thread/6fce9b7b-4a13-4c8d-8c3e-562667851baa/) but my results are not consistent.Sometimes it works, sometimes not. Still looking.
Cheeso
A: 

Use the DoEvents() code as shown here:
http://blogs.microsoft.co.il/blogs/tamir/archive/2007/08/21/How-to-DoEvents-in-WPF_3F00_.aspx

My actual code:

private void GreyOverlay()
{
    // make the overlay window visible - the effect is to grey out the display
    if (_greyOverlay == null)
        _greyOverlay = LogicalTreeHelper.FindLogicalNode(this, "overlay") as System.Windows.Shapes.Rectangle;
    if (_greyOverlay != null)
    {
        _greyOverlay.Visibility = Visibility.Visible;
        DoEvents();
    }
}

private void DoEvents()
{
    // Allow UI to Update...
    DispatcherFrame f = new DispatcherFrame();
    Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background,
                                             new Action<object>((arg)=> {
                                                     DispatcherFrame fr = arg as DispatcherFrame;
                                                     fr.Continue= false;
                                                 }), f);
    Dispatcher.PushFrame(f);
}
Cheeso
So you are using nested pumping... interesting. I didn't expect it would work.
Anvaka