2016-04-06 4 views
0

So lief ich in einem ui Update-Problem. Ich möchte in der Lage sein, eine Funktion A auszuführen, innerhalb der Funktion A gibt es einen Anruf B, der lange Zeit dauert, also wenn Funktion A zur Funktion B komme ich die Ansicht zu ProgressView ändern möchte, und zeige Fortschritt im laufenden Betrieb.Wie erzwinge ich die UI-Aktualisierung vor der Ausführung einer Aktion mit MVVM?

Was ich erreichen möge:

  • Aufruf eine Funktion A
  • Ausführung von A beginnt
  • Funktion B ist genannt
  • Funktion B ProgressDialog öffnet und zeigen Fortschritte während Funktion A wartet darauf, verarbeitet zu werden
  • Funktion B endet
  • Funktion A kann
  • Funktion A weiterhin beendet

Ich fand heraus, dass, wenn ich UI aktualisieren möchten i Anwendung Dispatcher verwenden, die eine Aktion auf UI-Thread ausgeführt wird.

FUNKTIONST:

Public Sub ShowWaitingScreen(workItems As List(Of WorkItem)) Implements IViewsLogic.ShowWaitingScreen 
    Dim waiting As WaitingDialogViewModel = New WaitingDialogViewModel(workItems, Sub() HideDialog()) 

    Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, Sub() 
                     _shell.DialogViewModel = waiting 
                        waiting.StartWorker 
                    End Sub) 


End Sub 

    Public Class WaitingDialogViewModel 
     Inherits ViewModelBase 
     Implements IDialog 
     Public Sub New(workItems As List(Of WorkItem), completeAction As Action) 
      _completeAction = completeAction 
      _workItems = workItems 
      ProgressValue = 0 
      StatusMessage = "Preparing" 
     End Sub 

     'Private WithEvents _worker As BackgroundWorker 
     Private _completeAction As Action 
     Private _progressValue As Integer 
     Private _statusMessage As String 
     Private ReadOnly _workItems As List(Of WorkItem) 

     Public Property ProgressValue As Integer 
      Get 
       Return _progressValue 
      End Get 
      Set(value As Integer) 

       _progressValue = value 
       Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, Sub() 
                         RaisePropertyChanged(Function() ProgressValue) 
                        End Sub) 
      End Set 
    End Property 

    Public Sub StartWorker() 
     For i As Integer = 1 To _workItems.Count() 
      ReportProgress(Convert.ToInt32(Math.Ceiling(100/(i + 1))), "Executing " + i.ToString() + " out of " + _workItems.Count().ToString()) 
      _workItems(i - 1).WorkerAction.Invoke() 
     Next 
     ReportProgress(100, "Dome") 
     _completeAction.Invoke() 
    End Sub 


    Public Property StatusMessage As String 
     Get 
      Return _statusMessage 
     End Get 
     Set(value As String) 
      _statusMessage = value 
      Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, Sub() 
                        RaisePropertyChanged(Function() StatusMessage) 
                       End Sub) 
     End Set 
    End Property 

    Private Sub ReportProgress(progress As Integer, text As String) 
     ProgressValue = progress 
     StatusMessage = text 
    End Sub 

End Class 

Das Problem, das ich jetzt bin vor ist, dass die Ergebnisse nicht übereinstimmen, wird manchmal WaitingDialogViewModel gezeigt, manchmal ist es nicht. Wie erzwinge ich die UI-Aktualisierung, bevor ich mit der Ausführung des Fortschritts beginne?

Antwort

0

Das Ansichtsmodell sollte das Ereignis PropertyChanged aufrufen, um die UI-Elemente zu benachrichtigen, dass sie sich selbst aktualisieren sollten. Wenn Sie keinen spezifischen Prop-Namen in PropertyChangedEventArgs angeben (also einfach null übergeben), werden alle gebundene Steuerelemente aktualisiert.