Moundir76
Messages postés281Date d'inscriptiondimanche 3 octobre 2010StatutMembreDernière intervention16 mai 2014
-
Modifié par Moundir76 le 30/07/2013 à 15:41
Moundir76
Messages postés281Date d'inscriptiondimanche 3 octobre 2010StatutMembreDernière intervention16 mai 2014
-
2 août 2013 à 08:35
Bonjour,
Avant insertion dans la BDD, je souhaite remplir un Datagridview pour permettre a l'utilisateur de vérifier les données.
Ainsi j'ai fait une Form Ajout qui contient un DatagridView.
Dans ma classe Objet, je fais a la méthode "AddThis()" de ma Form Preview :
Dans la classe :
For index = 0 To laRoue.listeNiveaux.Count - 1
Try
frmAjout.AddThis("val1","val2","val3","val4","val5","val6")
Catch ex As Exception
MsgBox(ex.ToString)
End Try
Next
Et dans la Form Ajout :
Public Sub AddThis(ByVal t1 As String, ByVal t2 As String, ByVal t3 As String, ByVal t4 As String, ByVal t5 As String, ByVal t6 As String)
Me.DataGridView10.Rows.Add(t1, t2, t3, t4, t5, t6)
End Sub
Quand j'execute en pas à pas, aucun souci tout se passe bien sauf que rien n'apparait dans le datagridview...
Par contre si je fais un bouton, et que dans l'evenement je fais un DataGridView10.Rows.Add("val1","val2","val3","val4","val5","val6"), la ligne s'insère bien...
Ben voyons, un thread maintenant!
Il est temps de fournir du code pour se faire une idée du problème.
Moundir76
Messages postés281Date d'inscriptiondimanche 3 octobre 2010StatutMembreDernière intervention16 mai 2014 1 août 2013 à 12:16
Je veux bien mettre mon code mais ça va être compliqué vu le nombre de ligne. Je pense avoir compris pourquoi cela ne fonctionne pas. En effet, depuis mon BackgroundWorker je vais effectuer mon traitement, sauf qu'une fois le traitement effectué, le backgroundworker s'arrete et donc le thread est détruit.
On se retrouve alors avec une form contenant le datagridview rempli qui a été ouvert par le thread T2, alors que celui ci n'existe plus. Donc maintenant je comprends pourquoi. Il ne me reste plus qu'a trouver si il est possible depuis le traitement de mon backgroundworker, d'utiliser le thread principal pour créer la form et remplir le datagridview...
Pourquoi ne pas simplement créer une instance de ton form preview dans le main, de l'afficher, et de démarrer un thread à l'interieur de celle-ci par une propriété publique ?
dim monpreview as new Ajout(val1,val2,val3...)
monpreview.show
monpreview.affiche
public class Ajout
inherits form
dim _val1, _val2... as ...
dim datagridview1 as new datagridview with {.parent = me }
private delegate sub delegueaffiche()
sub new(byval val1, byval val2....)
me.datagridview1.columns.add(...
_val1 = val1
_val2 = val2
end sub
sub affiche()
dim t as new threading.thread(addressof job)
t.start
end sub
private sub job()
'traitement a faire ici
'...
if me.invokerequired then
me.invoke(new delegueaffiche(addressof job))
else
me.datagridview1.rows.add(...)
end if
end sub
end class
Je n'ai jamais utilisé de delegate (car même avec le msdn je n'ai jamais réussi à appliquer un cas "réel" dans mes petites applications).
Au moins cette fois ci j'en vois un !
Cependant, mon souci est qu'une nouvelle fenêtre est instanciée, alors que je voudrais que ce soit celle que j'ai crée auparavant (sur visual studio) qui s'affiche. Je vais chercher et trouver comment faire !
Merci beaucoup pour ton aide Banana
EDIT : j'ai adapté pour avoir ma Form crée sur VS, cependant, même en passant par le delegate et le thread, lorsque le thread travaille, cela me bloque ma main form.
Bon un petit exemple simple avec simulation d'un long traitement à tester dans un projet vierge.
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim monpreview As New Ajout("test=", "bla")
AddHandler monpreview.FinTraitement, AddressOf FinTraitement
monpreview.Show()
monpreview.affiche()
End Sub
Private Sub FinTraitement(ByVal sender As Object, ByVal e As EventArgs)
MessageBox.Show("fin du traitement -> thread arrêté")
End Sub
End Class
Public Class Ajout
Inherits form
Dim _val1, _val2 As String
Dim datagridview1 As New datagridview With {.parent = Me}
Private Delegate Sub delegueaffiche(ByVal val1 As String, ByVal val2 As String)
Event FinTraitement(ByVal sender As Object, ByVal e As EventArgs)
Sub New(ByVal val1 As String, ByVal val2 As String)
Me.datagridview1.Columns.Add("", "test1")
_val1 = val1
_val2 = val2
End Sub
Sub affiche()
Dim t As New Threading.Thread(AddressOf job)
t.Start()
End Sub
Private Sub remplirdatagrid(ByVal valeur1 As String, ByVal valeur2 As String)
datagridview1.Rows.Add(valeur1, valeur2)
End Sub
Private Sub job()
Dim i As Integer
Do
Threading.Thread.Sleep(1000)
_val1 &= _val2
If Me.InvokeRequired Then
Me.Invoke(New delegueaffiche(AddressOf remplirdatagrid), _val1, _val2)
Else
remplirdatagrid(_val1, _val2)
End If
i += 1
If i > 4 Then Exit Do
Loop
RaiseEvent FinTraitement(Me, New EventArgs)
End Sub
End Class
cs_ShayW
Messages postés3253Date d'inscriptionjeudi 26 novembre 2009StatutMembreDernière intervention 3 décembre 201957 30 juil. 2013 à 20:11
Salut
Avez vous compris ?
moi non
d'abord
pourquoi écrire une class et utiliser frmAjout dans ta class
écris le tout dans frmAjout
2 Par contre si je fais un bouton, et que dans l'evenement je fais un DataGridView10.Rows.Add("val1","val2","val3","val4","val5","val6"), la ligne s'insère bien..
j'ai eu un cas semblable essaye d' ajouter Invalidate() après ta sub addthis
Salut banna32 on ne rigole plus avec ccm
Moundir76
Messages postés281Date d'inscriptiondimanche 3 octobre 2010StatutMembreDernière intervention16 mai 2014 31 juil. 2013 à 09:08
Salut,
Merci pour ta réponse. En fait, le programme s'execute dans mon main, le main va instancier des objets via ma classe. Lors de l'instanciation des objets, je vais ouvrir une fenêtre de prévisualisation des objets que je vais créer. C'est pour celà que j'ai choisi de faire comme ça. C'est un mauvais choix ?
J'ai essayé avec Invalidate et pas mieux...
La seule chose que j'ai réussi à faire c'est d'appeller le .Show() pendant l'insertion (on teste si la form n'est pas ouverte, sinon on la Show), Et la on voit la form apparaitre, le datagrid à l'air de se remplir vu que la scrollbar bouge, sauf que tous les controles se figent et deviennent blanc (y compris les labels), et j'ai ce fameux message "(Ne réponds pas)...
, je vois ma fenêtre se dessiner et que le datagrid se remplit bien. Cependant cette forme reste toujours figée au statut (Ne réponds pas).....
Une idée ?
EDIT : En fait le travail se fait via un backgroundworker, alors il n'est pas sur le même thread que mon main. Je pense donc que lorsque le processus du backgroundworker s'arrete, on ne peut plus acceder a la form qu'il a créé ! Avez vous une solution pour que mon frmPreview et datagridview1.rows.add("bla","bla","bla") se produise depuis le main thread ?
1 août 2013 à 12:16
On se retrouve alors avec une form contenant le datagridview rempli qui a été ouvert par le thread T2, alors que celui ci n'existe plus. Donc maintenant je comprends pourquoi. Il ne me reste plus qu'a trouver si il est possible depuis le traitement de mon backgroundworker, d'utiliser le thread principal pour créer la form et remplir le datagridview...
1 août 2013 à 12:53
Modifié par Moundir76 le 1/08/2013 à 14:33
Je n'ai jamais utilisé de delegate (car même avec le msdn je n'ai jamais réussi à appliquer un cas "réel" dans mes petites applications).
Au moins cette fois ci j'en vois un !
Cependant, mon souci est qu'une nouvelle fenêtre est instanciée, alors que je voudrais que ce soit celle que j'ai crée auparavant (sur visual studio) qui s'affiche. Je vais chercher et trouver comment faire !
Merci beaucoup pour ton aide Banana
EDIT : j'ai adapté pour avoir ma Form crée sur VS, cependant, même en passant par le delegate et le thread, lorsque le thread travaille, cela me bloque ma main form.
1 août 2013 à 19:45
Modifié par Moundir76 le 2/08/2013 à 08:45
J'ai adapté ton code pour que cela fonctionne avec ma winform prédéfinie !
Merci beaucoup pour ta patience.....
A+