PROBLEMA!! Popolare Un Datagridview da un thread diverso

mercoledì 18 novembre 2009 - 00.07

luka83 Profilo | Newbie

Ciao a tutti, sto creando un programmino con VB.Net 2008 nel quale ho un sul form principale un datagridview che dovrebbe essere aggiornato da un thread separato che riceve i dati trammite un socket tcp...

sul form principale ho il seguente codice

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

invece sulla classe Socket che viene lanciata su un'altro thread riceve dei messaggi dal socket tcp e trammite il codice:

Public Sub Start() Try Server = New TcpListener(LocalAddr, Port) Server.Start() While True Console.Write("Waiting for a connection... ") Dim client As TcpClient = Server.AcceptTcpClient() Console.WriteLine("Connected!") RaiseEvent Connected() data = Nothing ' Get a stream object for reading and writingd Stream = client.GetStream() Dim i As Int32 ' Loop to receive all the data sent by the client. i = stream.Read(bytes, 0, bytes.Length) While (i <> 0) ' Translate data bytes to a ASCII string. data = System.Text.Encoding.ASCII.GetString(bytes, 0, i) Console.WriteLine("Received: {0}", data) Form1.DGV_AddRow(data) i = stream.Read(bytes, 0, bytes.Length) End While client.Close() End While Catch ex As SocketException Console.WriteLine("SocketException: {0}", ex) Finally Server.Stop() End Try Console.WriteLine(ControlChars.Cr + "Hit enter to continue....") Console.Read() End Sub

Apparentemente tutto ok, ma mentre nella console ho la conferma della ricezione del messaggio nel Datagridview1 presente sul form principale rimane sempre vuoto....
Ringrazio anticipatamente per la vostra disponibilità
Luca

R3GM4ST3R Profilo | Junior Member

Ciao, due consigli
1) Mi pare strano che non dia errori o eccezioni, prova ad abilitare la visualizzazione di tutte le eccezioni gestite e non, dal menu Debug->eccezioni... flagga tutta la prima colonna (quella generalmente spuntata) e dai un giro al codice. Così facendo il debugger si fermerà ad ogni eccezione gestita e non, permettendoti di capire cosa non funziona senza far crashare l'applicazione.
2) Prova ad utilizzare un evento nella tua classe socket, quando ricevi la tua riga scateni l'evento RigaAggiunta(strRiga), nel form principale dichiari la variabile socket con il withevents, e quando istanzi la nuova classe, prima di far partire il thread, aggiungi l'handler dell'evento riga aggiunta nel form principale e probabilmente risolvi il problema.

Secondo me, non aggiunge la riga, perchè dal thread non ha accesso diretto al controllo grafico, di conseguenza non da errori ma non funziona.

>>P.S.
>>Form1.DGV_AddRow(data)
>>A dir la verità, Form1 è una classe, ma non è istanziata con i relativi controlli grafici, di conseguenza hai "finto" accesso agli oggetti grafici contenuti nel form, ma usando quella sintassi, in realtà non stai usando il form principale della tua applicazione...non so se mi sono spiegato...cmq se hai domande nn esitare.

Ciao!


Tutti sanno che una cosa è impossibile da realizzare, finché arriva uno sprovveduto che non lo sa e la inventa. (Albert Einstein)

luka83 Profilo | Newbie

Ho provato a spulciare tutte le eccezzioni del Debugger, ma nulla...
Ho provato anche a utilizzare un'evento, ma quando viene scatenato e il codice arriva su DGV_AddRow mi si impianta dandomi questo errore:
Impossibile aggiungere righe a livello di codice all'insieme di righe di DataGridView in caso di associazione a dati del controllo.
Qualcuno a qualche idea?
Luca

R3GM4ST3R Profilo | Junior Member

Scusa ho letto solo ora, probabilmente prima di popolare un datagrid, devi definirgli le colonne con i dati!
Fai prima a crearti un in un modulo a parte, questa roba quì :

>public DT as new datatable("DATI")

>private sub initData()
>DT.columns.add("STRINGADATI")
>end sub

Così facendo hai dichiarato una datatable globale dell'applicazione, all'avvio dell'applicazione stessa, richiami la initdata() in modo che crei la colonna relativa al tuo dato che devi inserire, successivamente modifichi la tua addriga del thread e la fai diventare

>DT.rows.add(new datarow(s_strStringadainserire))

o una roba simile, però passa attraverso gli oggetti che ti mette a disposizione il framework e dovresti risolvere il tuo problema!

Ah dimenticavo, per aggiornare la griglia, o usi un timer dentro al form principale, che ogni secondo imposta l'oggetto DT globale come datasource della datagrid, oppure sfrutta l'evento che ti avevo suggerito di creare in precedenza...

>Esempio con il timer :
>private sub timer() handles timer....
>me.datagridview1.datasource=DT
>end sub

Non è la soluzione più elegante, ma dovrebbe funzionare!


Ciao!

Tutti sanno che una cosa è impossibile da realizzare, finché arriva uno sprovveduto che non lo sa e la inventa. (Albert Einstein)

Teech Profilo | Expert

Ma il DataGridView che DataSource ha?
Secondo me devi agire nel seguente modo (in "pseudocodice"):

'Crei una collection generica di tipi che ti vengono restituiti
Dim list As List(Of String)
'Associ la collection al DataGridView
DataGridView1.DataSource=list
'Recuperi il messaggio dal Socket come stai facendo ora
'Aggiungi il messaggio alla collection
list.Add(STR)

Essendo la Collection associata al DataGridView il gioco dovrebbe essere fatto.
--------------
Maurizio Brini
--------------
Nessuna impresa è mai stata compiuta da un uomo ragionevole

cociredef Profilo | Newbie

Ciao.
sono nuovissimo in questo sito. Da qualche tempo programmo in Vb6 e ho deciso di passare a VB2008 Express.

In un semplicissimo form ho inserito un datagridview e un button.
Il Button mi collega via ADO ad un DB di Access.
Il collegamento funziona perchè il recordcount del recordset di access lo visualizzo su una textbox.

Il problema è che il datagridview rimane vuoto.
Non capisco dove sbaglio. Ecco il codice

Imports System.Windows.Forms
Imports System.Drawing
Imports System.Data


Public Class Form1

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

Dim SQLstr As String
Dim RS_GRID As New ADODB.Recordset
Dim Db_Conn As New ADODB.Connection
Dim StrConn_Access As String

StrConn_Access = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=C:\PROVA_DataGridView\GRID.mdb; Jet OLEDB:Database"

Db_Conn.Open(StrConn_Access)

SQLstr = "SELECT T_Auto.Auto, T_Auto.Colore, T_Prop.Proprieta FROM T_Auto INNER JOIN T_Prop ON T_Auto.Auto=T_Prop.Auto "
RS_GRID.Open(SQLstr, Db_Conn, ADODB.CursorTypeEnum.adOpenDynamic, ADODB.LockTypeEnum.adLockBatchOptimistic)

DataGridView1.DataSource = RS_GRID.DataSource
TextBox1.Text = "REC = " & RS_GRID.RecordCount

End Sub
End Class


Puoi darmi un aiuto ? Dove sbaglio ?

GRAZIE.
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5