WPF принудительное обновление графического интерфейса с помощью Dipatcher - PullRequest
0 голосов
/ 24 сентября 2010

Мне нужно только показать пользовательский элемент управления (часы с вращающимися стрелками) и этим заменить курсор мыши, проблема в том, что если я напишу:

Me.gridScreen.Visibility = Visibility.Visible
' some operations that takes about 1 second
Me.gridScreen.Visibility = Visibility.Hidden
(gridScreen is the grid that contains the user-control)

Очевидно, я ничего не вижу, потому что обновление пользовательского интерфейса происходит в конце процедуры. Я пробовал Me.UpdateLayout (), но он не работает.

Я пытался использовать диспетчер разными способами, но ни один из них не работает: - (

Это моя потерянная попытка:

(uCurClock - это пользовательский контроль, gridScreen a Grid, расположенный на верхнем уровне окна, с прозрачным фоном, который содержит пользовательский контроль)

Private Sub showClock()
    Dim thread = New System.Threading.Thread(AddressOf showClockIntermediate)
    thread.Start()
End Sub

Private Sub hideClock()
    Dim thread = New System.Threading.Thread(AddressOf hideClockIntermediate)
    thread.Start()
End Sub

Private Sub showClockIntermediate()
    Me.Dispatcher.BeginInvoke(DispatcherPriority.Normal, _
        New Action(AddressOf showClockFinale))
End Sub

Private Sub hideClockIntermediate()
    Me.Dispatcher.BeginInvoke(DispatcherPriority.Normal, _
        New Action(AddressOf hideClockFinale))
End Sub

Private Sub showClockFinale()
    Dim pt As Point = Mouse.GetPosition(Nothing)
    Me.uCurClock.Margin = New Thickness(pt.X - 9, pt.Y - 9, 0, 0)
    Me.gridScreen.Visibility = Visibility.Visible
    Me.Cursor = Cursors.None
    Me.UpdateLayout()
End Sub

Private Sub hideClockFinale()
    Me.gridScreen.Visibility = Visibility.Hidden
    Me.Cursor = Cursors.Arrow
    Me.UpdateLayout()
End Sub

Private Sub u_MouseMove(ByVal sender As System.Object, _
    ByVal e As MouseEventArgs) Handles gridScreen.MouseMove

    Dim pt As Point = e.GetPosition(Nothing)
    Me.uCurClock.Margin = New Thickness(pt.X - 9, pt.Y - 9, 0, 0)

    e.Handled = True
End Sub

Private Sub u_MouseEnter(ByVal sender As System.Object, _
    ByVal e As MouseEventArgs) Handles gridScreen.MouseEnter

    Me.uCurClock.Visibility = Visibility.Visible

    e.Handled = True
End Sub

Private Sub u_MouseLeave(ByVal sender As System.Object, _
    ByVal e As MouseEventArgs) Handles gridScreen.MouseLeave

    Me.uCurClock.Visibility = Visibility.Hidden

    e.Handled = True
End Sub

PIleggi

1 Ответ

1 голос
/ 24 сентября 2010

Проблема не в составлении сообщений, выполняемых диспетчером, а в том, что вы вообще выполняете длительную работу с диспетчером.Вы должны убедиться, что длительные / потенциально блокирующие операции выполняются в фоновом потоке.Самый простой способ сделать это с помощью компонента BackgroundWorker.

Извините за C #:

var backgroundWorker = new BackgroundWorker();

backgroundWorker.DoWork += delegate
{
    // long running work goes here
};
backgroundWorker.RunWorkerCompleted += delegate
{
    // change cursor back to normal here
};

// change cursor to busy here

// kick off the background task
backgroundWorker.RunWorkerAsync();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...