Hallo, wie kann ich während eine Suche ausgeführt wird, meine Oberfläche aktualisieren, damit irgendwie ersichtlich ist, das gerade eine Suche ausgeführt wird?
Habe mich bereits mit Threads beschäftigt, diese können aber nicht auf UI Elemente eines anderen Threads zugreifen.
Wichtig ist das in deiner Suchoperation das _worker.ReportProgress() aufgerufen wird. Du kannst mit der Methode entweder ein prozentualen Wert mit geben den du dann in der worker_ProgressChanged Methode mit e.ProgressPercentage abrufen kannst, oder aber du kannst die ReportProgress Methode mit 2 Parametern aufrufen:
Nein, nicht wenn Du die Methode "searchOperation" aufrufst. Die Abarbeitung der "searchOperation" durch einen anderen Thread wird mit der Zeile _worker.RunWorkerAsync(); gestartet. Der _worker wurde so eingestellt, dass sein "DoWork" effektiv die "searchOperation" ist, siehe _worker.DoWork += searchOperation;
Mit dem Stichwort "Threads" bist Du schon auf der richtigen Spur. "UI Elemente eines anderen Threads" ist aber eine etwas verquere Formulierung: es gibt einfach nur einen Thread, der das UI manipulieren darf. Folglich solltest Du Deine Suche in einem anderen Thread laufen lassen. Wenn sie fertig ist, kannst Du aus dem Suchthread mit Dispatcher.Invoke wieder zurück in den UI-Thread, um das Ergebnis anzuzeigen.
Den Hintergrundthread kannst Du z.B. über einen BackgroundWorker starten. Ein Beispiel samt Hintergundinfo findest Du in diesem Artikel aus dem MSDN-Magazin.
Sowas hatte ich mir schon fast gedacht. Allerdings wollte ich das vermeiden, weil damit ein zimlicher Haufen an Arbeit auf mich zukommt. Tja, wenn ich schon am Anfang daran gedacht hätte :(
Am einfachsten geht das vermutlich, wenn Du zur Akualisierung der Oberfläche den SynchronizationContext nutzt. Der Context sorgt dafür, dass die Anfrage wieder im UI thread ausgeführt wird.
SynchronizationContext.Current.Post( new SendOrPostCallback( ignore => meinControl.Refresh()), null);
In Silverlight wird eher dazu geraten den Dispatcher zu nutzen:
Wenn Du Anpassungen an Deinem Code vermeiden möchtest, könntest Du auch eine Art Splashscreen anzeigen während die Suche ausgeführt wird, und diesen Splashscreen in einem eigenen Thread laufen lassen. Beispiel gibt es hier.
Erstens steht wpf nicht im Text (sondern darunter, was ich zugegebenermassen übersehen habe), zweitens läuft der Splashscreen auch in wpf-Anwendungen, und drittens ist es eine kleine Fingerübung von keinen fünf Minuten, ihn auf wpf umzubauen. Das interessante an dem Beispiel ist das Prinzip, dass das Programm im UI-Thread arbeitet, während der Splashscreen in einem eigenen Thread läuft und aktualisiert werden kann, d.h. das Programm ist eigentlich single-threaded, erscheint dem Anwender aber nicht-blockierend.