WPF: Как сразу применить изменение к непрозрачности / фону? (WPF аналог метода WinForms Control.Update ()?) - PullRequest
1 голос
/ 26 февраля 2010

У меня есть приложение WPF, после нажатия кнопки приложение переходит к расчету, который может занять 4-10 секунд. Я хотел бы обновить непрозрачность фона и показать индикатор выполнения во время этой операции.

Для этого я использую этот код:

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. 

Когда я запускаю код, фон и непрозрачность не изменяются, пока не появится модальное диалоговое окно. Как я могу получить эти визуальные изменения прямо сейчас , прежде чем начнутся вычисления? В Windows Forms был метод Update () для каждого элемента управления, который делал это по мере необходимости, насколько я помню. Что такое аналог WPF?

Ответы [ 2 ]

1 голос
/ 26 февраля 2010

Что делать, если вы будете выполнять длительные вычисления в фоновом потоке? Как только они будут выполнены, отправьте результаты обратно в поток пользовательского интерфейса ...

Честно говоря, я подозреваю, что там нет ничего, что может решить вашу проблему. Может быть, вложенная накачка подойдет, но я действительно в этом сомневаюсь.

На всякий случай эта ссылка полезна: Создание более отзывчивых приложений с помощью Dispatcher

0 голосов
/ 26 февраля 2010

Используйте код DoEvents (), как показано здесь:
http://blogs.microsoft.co.il/blogs/tamir/archive/2007/08/21/How-to-DoEvents-in-WPF_3F00_.aspx

Мой фактический код:

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);
}
...