Możesz użyć Cursor.Current
.
// Set cursor as hourglass
Cursor.Current = Cursors.WaitCursor;
// Execute your time-intensive hashing code here...
// Set cursor as default arrow
Cursor.Current = Cursors.Default;
Jeśli jednak operacja mieszania jest naprawdę długa (MSDN określa to jako ponad 2-7 sekund), prawdopodobnie powinieneś użyć wizualnego wskaźnika sprzężenia zwrotnego innego niż kursor, aby powiadomić użytkownika o postępie. Bardziej szczegółowy zestaw wytycznych znajduje się w tym artykule .
Edycja:
Jak wskazał @Am, może być konieczne zadzwonienie Application.DoEvents();
po, Cursor.Current = Cursors.WaitCursor;
aby upewnić się, że klepsydra jest rzeczywiście wyświetlana.
Application.UseWaitCursor = true
iApplication.UseWaitCursor = false
Tak właściwie,
tymczasowo ustawia kursor Oczekiwanie, ale nie zapewnia, że kursor Oczekiwanie będzie wyświetlany do końca operacji. Inne programy lub elementy sterujące w twoim programie mogą łatwo zresetować kursor z powrotem do domyślnej strzałki, co w rzeczywistości dzieje się, gdy poruszasz myszą, gdy operacja jest nadal uruchomiona.
O wiele lepszym sposobem pokazania kursora Wait jest ustawienie właściwości UseWaitCursor w formie na true:
Spowoduje to wyświetlenie kursora oczekiwania dla wszystkich kontrolek w formularzu, dopóki ta właściwość nie zostanie ustawiona na false. Jeśli chcesz, aby kursor był wyświetlany na poziomie aplikacji, powinieneś użyć:
źródło
Opierając się na poprzednim, moim preferowanym podejściem (ponieważ jest to często wykonywana czynność) jest zawinięcie kodu kursora oczekiwania w klasę pomocniczą IDisposable, aby można go było używać za pomocą () (jeden wiersz kodu), brać parametry opcjonalne, uruchamiać kod wewnątrz, a następnie wyczyść (przywróć kursor).
Stosowanie:
źródło
Użycie UseWaitCursor jest łatwiejsze na poziomie formularza lub okna. Typowy przypadek użycia może wyglądać jak poniżej:
Aby uzyskać lepszy interfejs użytkownika, należy użyć asynchronii z innego wątku.
źródło
Moje podejście polegałoby na tym, aby wszystkie obliczenia były przetwarzane w tle.
Następnie zmień kursor w następujący sposób:
W zdarzeniu zakończenia wątku przywróć kursor:
Uwaga: można to również zrobić w przypadku określonych elementów sterujących, więc kursor będzie klepsydrą tylko wtedy, gdy mysz znajdzie się nad nimi.
źródło
OK, więc utworzyłem statyczną metodę asynchroniczną. Spowodowało to wyłączenie kontrolki uruchamiającej akcję i zmieniającej kursor aplikacji. Uruchamia akcję jako zadanie i czeka na zakończenie. Kontrola wraca do dzwoniącego podczas oczekiwania. Dzięki temu aplikacja pozostaje responsywna, nawet gdy ikona zajętości się obraca.
Oto kod z formularza głównego
Musiałem użyć osobnego programu rejestrującego dla akcji fikcyjnej (korzystam z Nlog), a mój główny program rejestrujący pisze w interfejsie użytkownika (bogate pole tekstowe). Nie byłem w stanie wyświetlić zajętego kursora tylko wtedy, gdy nad konkretnym kontenerem w formularzu (ale nie bardzo się starałem). Wszystkie kontrolki mają właściwość UseWaitCursor, ale nie ma to żadnego wpływu na kontrolki Próbowałem (może dlatego, że nie były na topie?)
Oto główny dziennik, który pokazuje, co dzieje się w oczekiwanej kolejności:
źródło
Korzystając z poniższej klasy, możesz uczynić sugestię dotyczącą pączka „wyjątkowym bezpiecznym”.
klasa CursorHandler
źródło
Okej, poglądy innych ludzi są bardzo jasne, ale chciałbym dodać trochę więcej:
źródło
W przypadku aplikacji Windows Forms bardzo przydatne może być opcjonalne wyłączenie interfejsu użytkownika. Więc moja sugestia wygląda następująco:
Stosowanie:
źródło
Użyj tego z WPF:
źródło