Você pode usar 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;
No entanto, se a operação de hash for realmente longa (o MSDN define isso como mais de 2 a 7 segundos), você provavelmente deve usar um indicador de feedback visual diferente do cursor para notificar o usuário sobre o progresso. Para um conjunto mais detalhado de diretrizes, consulte este artigo .
Editar:
Como apontou a @Am, talvez seja necessário ligar Application.DoEvents();
depois Cursor.Current = Cursors.WaitCursor;
para garantir que a ampulheta seja realmente exibida.
Application.UseWaitCursor = true
eApplication.UseWaitCursor = false
Na realidade,
define temporariamente o cursor Wait, mas não garante que o cursor Wait seja exibido até o final da sua operação. Outros programas ou controles dentro do seu programa podem facilmente redefinir o cursor de volta à seta padrão, como acontece de fato quando você move o mouse enquanto a operação ainda está em execução.
Uma maneira muito melhor de mostrar o cursor Wait é definir a propriedade UseWaitCursor em um formulário como true:
Isso exibirá o cursor de espera para todos os controles no formulário até você definir esta propriedade como false. Se você deseja que o cursor de espera seja mostrado no nível do aplicativo, você deve usar:
fonte
Com base no anterior, minha abordagem preferida (já que essa é uma ação executada com frequência) é agrupar o código do cursor de espera em uma classe auxiliar IDisposable para que possa ser usado com o uso de () (uma linha de código), use parâmetros opcionais, execute o código dentro e limpe (restaure o cursor) depois.
Uso:
fonte
É mais fácil usar UseWaitCursor no nível do formulário ou da janela. Um caso de uso típico pode se parecer abaixo:
Para uma melhor experiência de interface do usuário, você deve usar o Asynchrony de um thread diferente.
fonte
Minha abordagem seria fazer todos os cálculos em um trabalhador em segundo plano.
Então mude o cursor assim:
E no evento de término do segmento, restaure o cursor:
Observe que isso também pode ser feito para controles específicos; portanto, o cursor será a ampulheta somente quando o mouse estiver acima deles.
fonte
OK, então eu criei um método assíncrono estático. Isso desativou o controle que inicia a ação e altera o cursor do aplicativo. Ele executa a ação como uma tarefa e aguarda o término. O controle retorna ao chamador enquanto aguarda. Portanto, o aplicativo permanece responsivo, mesmo enquanto o ícone ocupado gira.
Aqui está o código do formulário principal
Eu tive que usar um logger separado para a ação fictícia (estou usando o Nlog) e meu logger principal está gravando na interface do usuário (uma caixa de rich text). Não consegui exibir o cursor ocupado apenas quando estava sobre um contêiner específico no formulário (mas não tentei muito.) Todos os controles têm uma propriedade UseWaitCursor, mas parece não ter efeito nos controles Eu tentei (talvez porque eles não estavam no topo?)
Aqui está o log principal, que mostra as coisas acontecendo na ordem que esperamos:
fonte
Com a turma abaixo, você pode fazer a sugestão de Donut "exceção segura".
a classe CursorHandler
fonte
Okey, a visão de outras pessoas é muito clara, mas eu gostaria de acrescentar algumas, como segue:
fonte
Para aplicativos Windows Forms, a desativação opcional de um controle de interface do usuário pode ser muito útil. Então, minha sugestão é assim:
Uso:
fonte
Use isso com o WPF:
fonte