Meilleur auteur de réponses
Usercontrol et BackgrounWorker?

Question
-
Bonjour a tous
j'ai fais un petit usercontrol avec un backgroundworker, mais quand j'ajoute l'usercontrol et que je l'exécute la form reste figé un moment.
donc d'après ce que je comprend c'est que l'usercontrol hérite de form1 de certaine propriété.
Par exemple, qui ce produit avec un move sur un controle dans l'usercontrol, cela ce produit !
Private Sub bg_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bg.ProgressChanged<br/> For i As Integer = 0 To 500<br/> Threading.Thread.Sleep(50)<br/> Panel1.Location = New Point(Panel1.Location.X, Panel1.Location.Y + i)<br/> Next<br/> End Sub
Quand je fait ce petit bout de code (en dehors de l'usercontrol) cela fonctionne plutot bien dans le backgroundworker, la form ne ce fige pas
La question est comment faire a partir d'un usercontrol des traitement lourd sans figé la form (l'application) en passant par un backgroundworker ou pas ?
En vous remerciant d'avance
Cordialement, Troxsa
Réponses
-
Donc avec une ProgressBar sur un formulaire et :
ProgressBar1.Style = ProgressBarStyle.Marquee ProgressBar1.Maximum = 10 ProgressBar1.MarqueeAnimationSpeed = 250 ProgressBar1.Step = 1
Cela me donne une animation de la progressbar. La feuille reste réactive (si j'ajoute par exemple des "checkbox" je peux les cocher/décocher sans latence perceptible).
Si on veut faire une animation perso, je pense qu'il serait peut-être préférable de déconnecter cette animation du "ProgressChanged" (je pense à un Timer) en particulier si le pourcentage n'est pas utilisé.
On ne pause que 50 ms mais on va le faire 500 fois ce qui fait 25 s pour exécuter une seule fois ProgressChanged ?!
Que fait exactement ce UserControl ? Il embarque à la fois un traitement d'arriere plan avec l'interface utilisateur qui va avec ?
Avec un panel avec fond rouge et un timer cela me donne par exemple :
Private Sub Form1_Shown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shown Timer1.Interval = 250 Timer1.Start() End Sub Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick Panel1.Width += 5 If Panel1.Width > Me.Width Then Panel1.Width = 0 End If End Sub
Je confirme j'ai ajouté un backgroundworker et le panel continue à s'élargir pendant qu'il s'exécute et totu reste réactif. Je pense que le problème original est que le ProgressChanged est trop long à s'exécuter...
Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".- Modifié Patrice ScribeMVP, Moderator mardi 30 novembre 2010 17:41 Ajout BackgroundWorker
- Proposé comme réponse Gabriel MongeonModerator mardi 30 novembre 2010 18:26
- Marqué comme réponse TroxsaEditor mardi 30 novembre 2010 19:44
Toutes les réponses
-
Bonjour,
ProgressChanged est exécuté sur le thread de l'interface utilisateur. Il faudrait donc que ce code soit le plus rapide possible et l'appeler le moins souvent possible (par exemple une erreur classique est de l'appeler depuis le travail d'arrière-plan même si le pourcentage d'avancement ne change pas ce qui va exécuter du code sur le UI thread pour rien).
Quel est le but de ce code ? Il n'utilise même pas le pourcentage. Si le but est de faire une animation pendant l'exécution du travail d'arrière-plan la progress bar dispose d'un mode permettant de faire cela...
Please always mark whatever response solved your issue so that the thread is properly marked as "Answered". -
Patrice Scribe
Oui c'est dans le but de faire une animation d'un control.
vous dites que la progressbar dispose d'un mode permettant de faire cela ?
Hum ... c'est a dire ? pourriez vous me donner un exemple ou me mettre sur la piste. Faut t'il que l'usercontrol herite du control progress bar ?A bientot
Cordialement, Troxsa -
Donc avec une ProgressBar sur un formulaire et :
ProgressBar1.Style = ProgressBarStyle.Marquee ProgressBar1.Maximum = 10 ProgressBar1.MarqueeAnimationSpeed = 250 ProgressBar1.Step = 1
Cela me donne une animation de la progressbar. La feuille reste réactive (si j'ajoute par exemple des "checkbox" je peux les cocher/décocher sans latence perceptible).
Si on veut faire une animation perso, je pense qu'il serait peut-être préférable de déconnecter cette animation du "ProgressChanged" (je pense à un Timer) en particulier si le pourcentage n'est pas utilisé.
On ne pause que 50 ms mais on va le faire 500 fois ce qui fait 25 s pour exécuter une seule fois ProgressChanged ?!
Que fait exactement ce UserControl ? Il embarque à la fois un traitement d'arriere plan avec l'interface utilisateur qui va avec ?
Avec un panel avec fond rouge et un timer cela me donne par exemple :
Private Sub Form1_Shown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shown Timer1.Interval = 250 Timer1.Start() End Sub Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick Panel1.Width += 5 If Panel1.Width > Me.Width Then Panel1.Width = 0 End If End Sub
Je confirme j'ai ajouté un backgroundworker et le panel continue à s'élargir pendant qu'il s'exécute et totu reste réactif. Je pense que le problème original est que le ProgressChanged est trop long à s'exécuter...
Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".- Modifié Patrice ScribeMVP, Moderator mardi 30 novembre 2010 17:41 Ajout BackgroundWorker
- Proposé comme réponse Gabriel MongeonModerator mardi 30 novembre 2010 18:26
- Marqué comme réponse TroxsaEditor mardi 30 novembre 2010 19:44
-
Effectivement, comme PAtrice la signifié, un timer permet de faire l'Animation. Mais encore là il faut pas trop en mettre dans le Tick du timer et ne pas mettre l'interval trop petit. Normalement, en 250ms l'oeil ne devrait pas s'apercevoir et cela devrait donner une impression de continu.
Microsoft MVP C# || gabrielmongeon.com || LinkedIn -
Merci pour vos conseils.
Le but de cette usercontrol est de faire un peux comme si on tournais une page a l'aide d'un bouton a droite et gauche.
je sais pas trop si vous voyez ce que je veux dire ...
dans le code que j'ai donné c'est, effectivement, juste la base de ce qui a été fait pour commencé l'usercontrol, en voyant que ça fonctionnais pas, j'ai fais quelle recherche. En voyant qu'il y a pas grand chose sur ce probleme j'ai pas continué mon code et j'suis venu ici pour une aide :)
Je vais essayé de faire ce que vous m'avez conseillés :)
A bientot
Cordialement, Troxsa -
Avec le timer ça fonctionne tres bien, merci
Voila ce que j’essaie de faire...
Imports System.ComponentModel Public Class UserControl1 Private WithEvents timer1 As New Timer Private oPos As Integer = 0 Sub New() ' Cet appel est requis par le concepteur. InitializeComponent() ' Ajoutez une initialisation quelconque après l'appel InitializeComponent(). timer1.Enabled = False timer1.Interval = 10 End Sub Private Enum oDirection Droite = 0 Gauche = 1 Haut = 2 Bas = 3 End Enum Private Sub boutoncliquer(ByVal odirect As oDirection) Panel1.Size = New Size(Panel1.Size.Width, Panel1.Size.Height) Panel1.Dock = DockStyle.None timer1.Enabled = True End Sub Private Sub timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles timer1.Tick Panel1.Location = New Point(Panel1.Location.X + oPos, Panel1.Location.Y) oPos += 1 If Panel1.Location.X = Me.Location.X Then timer1.Enabled = False End If End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click boutoncliquer(oDirection.Droite) End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click boutoncliquer(oDirection.Gauche) End Sub Private newPanel As New Panel <Browsable(True), Category("Panel"), Description("Ajoute une interface Panel page")> _ Public Property xPanel As Control Get Return newPanel End Get Set(ByVal value As Control) newPanel = value End Set End Property End Class
Mon userControl a deux boutons (a doite, et l'autre a gauche), ses deux boutons sont tout les deux docker (un a droite et l'autre a gauche), le panel lui est au centre docker aussi, je souhaiterais pouvoir ajouté plusieurs panels dans une collection (propriété) et de pouvoir choisir un de ses panels pour y déposer des contrôles (une sorte de wizard)
je sais pas trop encore comment tout faire car je me lance dans quelle que chose que je connais encore tres mal ;)
Merci pour autre aide
Cordialement, Troxsa