public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
button1.BackColor = Color.Lime;
Thread.Sleep(5000);
button1.BackColor = Color.DarkGreen;
}
}
button1 is already DarkGreen. when I click button1, nothing changes.How can I observe this change for 5 seconds?
3 Réponses :
La raison pour laquelle cela ne fonctionne pas est que le thread.sleep () bloque le fil de remplir.
La fenêtre est uniquement redessinée lorsque l'application ne fait rien, c'est-à-dire après la fin de votre méthode. Si vous supprimez la ligne où vous le modifiez en Vous devez utiliser une minuterie pour résoudre votre problème. P> Si vous voulez, vous pouvez le forcer à rafraîchir l'interface tôt sans quitter la méthode avec un appel à DarkGreen Code>, vous le verrez changer de couleur après cinq secondes. P> Application.Deevents (); code> qui reflétera les modifications que vous avez apportées des changements de couleur. P> button1.BackColor = Color.Lime;
Application.DoEvents()
Thread.Sleep(5000);
button1.BackColor = Color.DarkGreen;
Pas la meilleure suggestion. Le design de OP pourrait être considéré comme faux. Vous pouvez améliorer cette réponse en ajoutant un lien à un meilleur conseil d'interface utilisateur.
Je pouvais mais c'est en dehors de la portée de la question, il semble que OP a essayé de changer de couleur de bouton pendant cinq secondes, juste pour voir comment, et a accidentellement trébuché lors d'une quirk des applications formes en ce sens qu'elles ne mettent à jour que lorsque le fil n'est pas occupé à faire autre chose. J'ai expliqué comment les applications de formes fonctionnent et pourquoi le test de changement de couleur ne fonctionnait pas et que le sommeil de fil est une mauvaise idée dans une application de formulaires. Je pense que cela devrait être suffisant.
Pour autant que je comprends le problème avant que le bloc de code ne soit sorti de l'événement. Et nous pouvons surmonter ce problème en appelant l'application.Deevents () dans le bloc de code. Merci pour l'aide
Il vous suffit d'appeler bouton1.update (); code> pour mettre à jour le bouton immédiatement, pas besoin d'appeler application.devents () code>. Vous voudrez peut-être aussi envisager une manière async / attendre la voie que j'ai décrite dans l'autre réponse Commentaires qui fait l'affaire sans bloquer le fil d'interface utilisateur.
L'académique, car il s'agit fondamentalement de la même chose, la mise à jour () force simplement un message interopt pour redessiner la fenêtre, les doigts d'application indiquent que Windows de faire tout ce qui est mis en file d'attente qui inclura le même message. Oui, vous devriez utiliser ASYNC Await pour le faire correctement, mais je ne pense pas que l'OP essaie d'obtenir un bouton de figurer pendant 5 secondes, ils essaient de déterminer comment changer la couleur d'un bouton. L'exemple ASYNC ci-dessous n'est pas bon non plus, car vous ne devez pas accéder à des contrôles directement à partir d'un fil séparé.
Je ne recommanderais pas d'utiliser WHING.SLEEP () car il gelait votre interface. De plus, vous devez actualiser le bouton afin que les modifications affichées.
Vous pouvez utiliser ASYNC et des méthodes d'attente pour retarder votre changement de couleur de votre bouton.
Ajouter Async après le mot-clé privé sur la fonction Bouton1_Click
et créer la fonction de tâche asynchrone et retirez la fonction thread.sleep () avec attendre en attente ();
Pas besoin d'appeler bouton1.refresh (); code> parce que le fil d'interface utilisateur n'est pas bloqué et fera la repeindre après la mise en place de la couleur de la chaux.
Votre problème est parce que le fil d'interface utilisateur est bloqué. Vous devez exécuter cette logique dans un fil séparé. Essayez ce code à la place:
private async void button1_Click(object sender, EventArgs e)
{
button1.BackColor = Color.LimeGreen;
await Task.Run(() =>
{
System.Threading.Thread.Sleep(5000);
button1.BackColor = Color.DarkGreen;
});
}
Pas besoin de TASK.RUN CODE> dans une méthode ASYNC dans ce cas. Vous accédez également à l'élément d'interface utilisateur d'un autre fil lorsque vous définissez le Backcolor code> du bouton dans la tâche .Run code>. Le faisant simplement dans une méthode asynchrone suffirait: bouton1.backcolor = couleur.limegreen; attendre la tâche.delay (5000); bouton1.backcolor = color.darkgreen; Code>
Cela ne ressemble pas à la sécurité du fil, cela pourrait fonctionner dans ce cas, mais ce n'est pas une bonne pratique, vous devez utiliser begininvoke () code> si vous allez accéder à des commandes d'un formulaire à partir d'un fil séparé.
WPF ou Winfrom?
Essayez d'insérer une touche1.Refresh (); avant le sommeil.
Cela pourrait être mieux atteint dans JavaScript, si vous utilisez WinForms ou MVC. Pouvez-vous être plus précis sur votre problème?
JavaScript? c'est c #
@Gottz S'il fait une page Web (par conséquent, pourquoi j'ai demandé "Winforms ou MVC"), la modification de la couleur d'un bouton est mieux faite avec JavaScript que C # CodeBeHind.
De plus, votre code actuel gelera l'interface qui n'est pas ce que je peux imaginer que vous voulez.
Je vous recommande de ne pas faire ça. Lisez à propos de Programmation asyncononne et les interfaces sensibles .
Dupliqué possible de Gardez le fil de l'interface utilisateur réactif lorsque vous courez longtemps Tâche sous Windows forme
C'est WinForm. Et oui, je sais que cette interface gèle. La principale chose que je voulais apprendre était que les changements de couleur n'étaient pas faits avant la fin du bloc de code. et comment puis-je faire cela. Merci pour tout le monde
Si vous souhaitez modifier la couleur du bouton après un certain nombre de secondes, apportez la touche
.Cliquez sur () CODE> Handler ASYNC (ASYNC privé Bouton1_Cliquez (Expéditeur d'objet, Eventargs e) Code>) , Définissez la première couleur, puisattendre la tâche.delay (5000) code>, puis réglez la deuxième couleur. Si nécessaire, désactivez le bouton comme la première chose et activez-le à nouveau avant que le METOD ne revienne.