Hier ist ein Beispiel dafür, wie man einen modalen Dialog, während ein Verfahren, in dem ausgeführt wird, angezeigt werden kann Anrufformular. Der Trick besteht darin, den Dialog dazu zu bringen, die Methode aufzurufen, damit sie auch weiß, wann diese Methode abgeschlossen ist, damit sie sich selbst schließen kann.
Dialog:
'The method to execute while the dialogue is displayed.
Private action As [Delegate]
'The arguments to the method to be executed.
Private args As Object()
'The result of the executed method, if there is one, can be retrieved from here.
Public Property Result As Object
Public Sub New(action As [Delegate], ParamArray args As Object())
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
Me.action = action
Me.args = args
End Sub
Private Sub Form2_Shown(sender As Object, e As EventArgs) Handles Me.Shown
'Make sure that the dialogue is displayed fully.
Refresh()
'Execute the method once the dialogue is displayed.
Result = action.DynamicInvoke(args)
'Close the dialogue when the method completes.
Close()
End Sub
Wenn der Dialog erstellt wird, nimmt es einen Vertreter, das heißt einen Verweis auf ein Verfahren und eine Liste von Argumenten für diese Methode. Wenn der Dialog angezeigt wird, ruft er diesen Delegaten auf und führt dadurch die Methode aus. Wenn die Methode abgeschlossen ist, wird das Ergebnis über eine öffentliche Eigenschaft verfügbar gemacht und anschließend geschlossen.
Caller:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Using dialogue As New Form2(New Func(Of Integer, String)(AddressOf GenerateRandomText), 10)
dialogue.ShowDialog()
Dim result = CStr(dialogue.Result)
MessageBox.Show(result)
End Using
End Sub
Private Function GenerateRandomText(length As Integer) As String
Const chars = "abcdefghijklmnopqrstuvwxyz"
Dim rng As New Random
Dim result = String.Empty
For i = 1 To length
result &= chars(rng.Next(chars.Length))
'Simulate a long-running task.
Thread.Sleep(500)
Next
Return result
End Function
In dem Beispiel enthält der Anrufer eine Methode, die eine String
von zufälligen Kleinbuchstaben erzeugt. Es zeigt einen Dialog an und weist diesen Dialog an, diese Methode aufzurufen, um eine String
von 10 Zeichen zu erstellen. Sobald der Dialog geschlossen ist, wird der erzeugte String
aus dem Dialog abgerufen und angezeigt.
Beachten Sie, dass ich den Anruf Thread.Sleep
hinzugefügt habe, nur um die Dinge ein wenig länger dauern, so dass der Dialog nicht verschwindet, sobald es angezeigt wird. Beachten Sie auch, dass der Aufruf Refresh
im Dialog erforderlich ist, da die lang laufende Methode auf dem UI-Thread ausgeführt wird, die andernfalls das korrekte Zeichnen des Dialogs verhindert.Um dies alles richtig zu machen, sollte die Methode wirklich in einem sekundären Thread aufgerufen werden, aber das macht die Dinge etwas komplizierter.
EDIT:
Wenn Sie ein BackgroundWorker
zum Dialogform hinzufügen können Sie das Verfahren auf einem sekundären Thread ausgeführt werden. Stellen Sie nur sicher, dass die von Ihnen ausgeführte Methode nicht auf die Benutzeroberfläche zugreift oder dass Sie Probleme mit mehreren Threads haben.
Dialog:
'The method to execute while the dialogue is displayed.
Private action As [Delegate]
'The arguments to the method to be executed.
Private args As Object()
'The result of the executed method, if there is one, can be retrieved from here.
Public Property Result As Object
Public Sub New(action As [Delegate], ParamArray args As Object())
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
Me.action = action
Me.args = args
End Sub
Private Sub Form2_Shown(sender As Object, e As EventArgs) Handles Me.Shown
BackgroundWorker1.RunWorkerAsync()
End Sub
Private Sub BackgroundWorker1_DoWork(sender As Object, e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork
'Execute the method on a background thread.
Result = action.DynamicInvoke(args)
End Sub
Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
'Close the dialogue when the method completes.
Close()
End Sub
Die offensichtliche Wahl ist ein modaler Dialog, das heißt einer Form angezeigt durch seine 'ShowDialog' Methode aufrufen. Nur nicht, dass sich das Formular schließen müsste, weil 'ShowDialog' blockiert, bis das Formular geschlossen wird, so dass der Aufrufer den Dialog nicht schließen kann. – jmcilhinney
habe ich schon gemacht. showdialog(), um ein neues modales Formular zu öffnen, aber das Problem ist, dass ich diesen Dialog schließen kann, nachdem die Abfrage abgeschlossen ist? – Maki
Warum benötigen Sie überhaupt einen Ladebildschirm? Wie langsam ist es? Oder warum nicht die ganze Zeit damit verbringen, die Geschwindigkeit zu erhöhen, anstatt den Benutzer davon abzulenken, wie schlecht er funktioniert. – Plutonix