WPF: How to apply a change to an Opacity/Background immediately? (WPF analog to WinForms Control.Update() method?)
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 ope开发者_JAVA技巧ration.
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?
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
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);
}
精彩评论