System.InvalidOperationException*: 'Impossible d'appeler Invoke ou BeginInvoke sur un contrôle tant que le han
Bonjour à tous,
Je me permets de vous solliciter suite à un problème que je rencontre.
Je développe actuellement une application de surveillance.
Celle ci se compose d'une Form Windows dans laquelle, nous avons :
- un bouton (btn_Test_CLick)
- une TextBox (txBx_Lecture_CSV)
Ce que je cherche à faire :
- en cliquant sur le bouton, je crée un file System Watcher qui devra détecter si un fichier est modifié sur le répertoire surveillé
- lorsque le fichier est effectivement modifié, un message du genre "le fichier est modifié"
Pour cela, je dispose de 2 classes : Form1.vb et bouton.vb dont voici les codes :
Form1 .vb
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| Imports System.IO
Imports System.Threading
Public Class Form1
'--Ecoute du répertoire
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'--AU chargement de la forme Windows, on déclare un nouvel objet de type bouton
mBouton = New bouton
End Sub
'-----------------------------------------------------------------------------------------------------------------------------
'--Déclaration du WithEvent dans la classe
Private WithEvents mBouton As bouton
Private Sub btn_Test_CLick_Click(sender As Object, e As EventArgs) Handles btn_Test_CLick.Click
Application.DoEvents()
mBouton.simule_clic(sender, e)
End Sub
End Class |
bouton.vb
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| Imports System.IO
Public Class bouton
'--définir un evenement
Public Event Click_Bouton_Test(ByVal sender As Object, ByVal e As EventArgs)
'--Méthode appelée
Public Sub simule_clic(ByVal sender As Object, ByVal e As EventArgs)
Dim watcher = New FileSystemWatcher("C:\test_robot")
'--Déclaration des notifications
'-- Sur les attributs, la date de création, le nom du répertoire
'-- le nom du fichier, le dernier accès, la dernière écriture
'-- sur la taille ou la sécurité du fichier
watcher.NotifyFilter = NotifyFilters.Attributes Or
NotifyFilters.CreationTime Or
NotifyFilters.DirectoryName Or
NotifyFilters.FileName Or
NotifyFilters.LastAccess Or
NotifyFilters.LastWrite Or
NotifyFilters.Security Or
NotifyFilters.Size
'--Syntaxe de l'instruction AddHandler
AddHandler watcher.Changed, AddressOf OnChanged
AddHandler watcher.Created, AddressOf OnCreated
AddHandler watcher.Deleted, AddressOf OnDeleted
AddHandler watcher.Renamed, AddressOf OnRenamed
AddHandler watcher.Error, AddressOf OnError
'--Filtre uniquement sur les fichiers textes
watcher.Filter = "*.txt"
'--inclusion des sous-répertoires
watcher.IncludeSubdirectories = True
'--obtient une valeur indiquant si le composant est activé
watcher.EnableRaisingEvents = True
End Sub
Public Sub OnChanged(sender As Object, e As FileSystemEventArgs)
If e.ChangeType <> WatcherChangeTypes.Changed Then
Return
End If
Dim dt As DateTime = Now()
Static tp As Long = 0
If e.ChangeType = WatcherChangeTypes.Changed Then
'--Systeme de timer pour empecher que l'evenement Onchanged ne se déclenche 2 fois consécutivement
If ((dt.Ticks - tp) < 400000 AndAlso e.ChangeType = WatcherChangeTypes.Changed) Then
Return
End If
tp = dt.Ticks
Form1.Invoke(New MethodInvoker(Sub()
Form1.txtBx_Operations_Fichiers.AppendText("Changement du fichier : " + e.FullPath.ToString + vbCrLf + vbCrLf)
End Sub))
End If
End Sub
Public Sub OnCreated(sender As Object, e As FileSystemEventArgs)
Dim value As String = $"Created: {e.FullPath}"
Form1.Invoke(New MethodInvoker(Sub()
Form1.txtBx_Operations_Fichiers.AppendText("Création du fichier : " + e.FullPath.ToString + vbCrLf + vbCrLf)
End Sub))
End Sub
End Class |
Le problème se situe au niveau de cette instruction dans la classe bouton.vb où je cherche à mettre à jour la textBox dans la Form:
Code:
1 2 3 4
| Form1.Invoke(New MethodInvoker(Sub()
Form1.txtBx_Operations_Fichiers.AppendText("Création du fichier : " + e.FullPath.ToString + vbCrLf + vbCrLf)
End Sub))
End Sub |
J'ai le message comme quoi il est impossible d'appeler la méthode Invoke.
J'ai compris qu'il s'agissait d'un problème de Thread ou j'essayais de mettre à jour la textBox avec un Thread différent de celui qui avait crée la Windows Form et du coup, cela n'était pas sécurisé.
Ma question est la suivante : comment puis-je écrire dans ma Textbox quand même ?
Je suis passé par la création d'un nouveau Thread, j'ai voulu utilisé la methode Shown (plutot que Form1_Load), et les delegates mais rien n'y fait, je m'y prend mal.
Pouvez-vous m'apporter votre aide ?
Par avance, merci