2010-09-23 5 views
0

Je n'ai besoin que d'afficher un contrôle personnalisé (une horloge avec des aiguilles rotatives) et de remplacer le curseur de la souris si j'utilise un fichier .cur ou .ani pour remplacer le curseur de la souris Me.CUrsor = Nouveau curseur ("chemin absolu du fichier .ani") il n'y a pas de problème: je peux changer le curseur pendant une procédure: mais la qualité de l'animation est très mauvaise, et, pour d'autres raisons aussi, Je préférerais utiliser mon petit contrôle utilisateur. Le problème est que si j'écris:wpf forcer la mise à jour de la fenêtre de l'interface utilisateur lors d'une procédure

Me.gridScreen.Visibility = Visibility.Visible

'certaines opérations qui prend environ 1 seconde

Me.gridScreen.Visibility = Visibility.Hidden

(gridScreen est la grille qui contient le contrôle de l'utilisateur)

Évidemment, je ne vois rien, parce que la mise à jour de l'interface utilisateur se produit à la fin de la procédure. J'ai essayé Me.UpdateLayout(), mais cela ne fonctionne pas.

Je tryed d'utiliser le dispacker dans de nombreux cours, mais aucun qui fonctionne :-(

Ceci est ma tentative perdue:

(uCurClock est le usercontrol, gridScreen une grille placée au plus haut niveau dans la fenêtre, avec un fond trasparent, qui contient le usercontrol)

Private Sub showClock()G 
    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

Répondre

1

Alors que le code suivant fera ce que vous demandez, je s uspect cela ne vous aidera pas réellement, puisque vous avez mentionné l'animation. Vous allez devoir utiliser plusieurs threads. Cependant, juste pour démontrer pourquoi c'est, voici quelque chose qui répond à la question que vous avez posée:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button1.Click 

    uc1.Visibility = Visibility.Visible 
    Cursor = Cursors.Wait 

    ' Push visibility changes now. 
    ' (Sort of like DoEvents - and a horrible idea for exactly the same 
    ' reasons that DoEvents was a total train wreck. Never actually do 
    ' this - use a background thread instead.) 
    Dim df As New DispatcherFrame(True) 
    Dispatcher.BeginInvoke(Sub() df.Continue = False, DispatcherPriority.ContextIdle) 
    Dispatcher.PushFrame(df) 

    Thread.Sleep(1000) 

    ClearValue(CursorProperty) 
    uc1.Visibility = Visibility.Hidden 

End Sub 

En supposant que vous avez un usercontrol appelé UC1 sur la page, cela forcera à être visible pendant l'exécution de votre procédure lente .

Mais aucune animation ne sera exécutée. Le problème est que, si vous faites quelque chose de lent sur le thread de l'interface utilisateur, le thread de l'interface utilisateur ne peut rien faire d'autre - il ne peut pas exécuter d'animations, il ne peut pas répondre aux entrées utilisateur. Fondamentalement, l'interface utilisateur est gelée. La seule raison pour laquelle le code affiché ici rend même le contrôle de l'utilisateur visible est qu'il dit fondamentalement "faire fonctionner le thread de l'interface utilisateur en cours", ce qui a pour effet secondaire de traiter votre modification à la propriété Visible.

Mais les animations se produisent également sur le thread de l'interface utilisateur. Si vous voulez faire cela correctement, vous devez faire le travail sur un thread d'arrière-plan, éventuellement en utilisant BackgroundWorker, ou en écrivant votre propre code d'enfilage.

+0

Griffitshs: Merci! J'ai utilisé le curseur .ani mais votre réponse est très intéressante! – lamarmora

1

référence DispatcherFrame Class Reference

bonne ole DoEvents pour WPF !!!

Public Sub DoEvents() 
    Dim frame As New DispatcherFrame() 
    Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, New DispatcherOperationCallback(AddressOf ExitFrame), frame) 
    Dispatcher.PushFrame(frame) 
End Sub 

Public Function ExitFrame(ByVal f As Object) As Object 
    CType(f, DispatcherFrame).Continue = False 
    Return Nothing 
End Function 
Questions connexes