Problème de cross threading avec un DataGridView

Résolu
Signaler
-
 Utilisateur anonyme -
J'essaye d'ajouter une nouvelle ligne à un datagridview depuis un autre thread sur une autre Class. Si je ne suis pas sur un thread pour lancer la commande d'ajout d'un nouvelle ligne ca se passe bien mais ca me pose un problème qui m'a poussé avoir besoin de ce thread (calcule lourd et donc freeze de l'interface). Donc j'ai besoin de ce thread mais quand je passe par lui et que je veux ajouter une nouvelle ligne j'obtient un message d'erreur qui me dit que je dois ajouter des colonnes avant d'ajouter des lignes. Ce qui montre a mon avis que je dois etre sur un mauvais thread malgrès que j'ai essayé de passer par un invoke comme montre l'example du code ci-dessous. Il faut noter aussi que je débute en C# mais je viens du Java.

public class MainClass {

private static Gui gui;

static void Main()
{
Application.EnableVisualStyles();
gui = new Gui();
Application.Run(gui);
}

public static Gui getGui()
{
return gui;
}
}

public class A {

public A () {
Thread t = new Thread(new ThreadStart(launch));
t.start();
//if i don't use a thread here and i directly call launch() the code works except i have my freeze problem
}

public void launch() {
Object[] row = {"a","b","c","d"}
Gui gui = MainClass.getGui();
gui.addRowObject(row);
}
}

public class Gui {

//Here all stuff of the GUI
private DataGridView dgv;

private delegate void addRow(Object[] objs);
public void addRowObject(Object[] objs)
{
if (this.dgv.InvokeRequired)
{
this.dgv.Invoke(new addRow(addRowObject), objs);
}
else
{
this.dgv.Rows.Add(objs);
}
}

4 réponses

Messages postés
3466
Date d'inscription
lundi 16 octobre 2000
Statut
Membre
Dernière intervention
30 octobre 2008
55
Plus "proprement" sinon :





Mx



<hr size="2" width="100%">

using System;

using System.Threading;

using System.Windows.Forms;



namespace Test

{

public class Gui : Form

{

private Thread t;

private DataGridView dgv;



public Gui()

{

IntializeComponent();

t = new Thread(new ThreadStart(Launch));

t.Start();

}



public void Launch()

{

Object[] row = { "a", "b", "c", "d" };

Invoke(new Gui.AddRow(AddRowObject), new object[] { row });

}



private void IntializeComponent()

{

dgv = new DataGridView();


this.dgv.Columns.Add(new DataGridViewColumn(new
DataGridViewTextBoxCell()));

this.Controls.Add(dgv);

}



public delegate void AddRow(Object[] objs);

public void AddRowObject(Object[] objs)

{

foreach(object o in objs)

this.dgv.Rows.Add(o.ToString());

}



public static void Main()

{

Application.EnableVisualStyles();

Application.Run(new Gui());

}

}

}
Messages postés
3466
Date d'inscription
lundi 16 octobre 2000
Statut
Membre
Dernière intervention
30 octobre 2008
55
Voila, de cette facon ca va marcher.

Apparement, tu es obligé d'ajouter un DataGridViewColumn a ton DataGridView

Autrement, sache que, a l'instar des accesseurs en java, en C# on a les
propriétés (avec des méthodes get et set, voir comment j'ai fait pour
la variable gui)



Sinon, j'aurais mis le thread dans la classe gui, mais tu as peut etre une raison d'avoir créé une classe séparée





Mx


<hr size="2" width="100%">

using System;

using System.Threading;

using System.Windows.Forms;



namespace Test

{

public class MainClass

{

private static Gui gui;



public static void Main()

{

Application.EnableVisualStyles();

gui = new Gui();

Application.Run(gui);

}



public static Test.Gui Gui

{

get { return gui; }

// set { gui = value; }

}

}



public class A

{



private Thread t;

public A()

{

t = new Thread(new ThreadStart(launch));

}



public void StartThread()

{

t.Start();

}



public void launch()

{

Object[] row = { "a", "b", "c", "d" };

Gui gui = MainClass.Gui;


gui.Invoke(new Gui.addRow(gui.addRowObject), new object[] { row });

}

}



public class Gui : Form

{

private DataGridView dgv;

private A a;

public Gui()

{

IntializeComponent();

a = new A();

a.StartThread();

}



private void IntializeComponent()

{

dgv = new DataGridView();


this.dgv.Columns.Add(new DataGridViewColumn(new
DataGridViewTextBoxCell()));

this.Controls.Add(dgv);

}



public delegate void addRow(Object[] objs);

public void addRowObject(Object[] objs)

{

//this.dgv.DataSource = objs;

foreach(object o in objs)

this.dgv.Rows.Add(o.ToString());

}

}

}

Je te remercie bien je vais essayer de mettre ca dans mon code voir si j'arrive a m'en sortir.

Nikel j'ai suivi la version propre et j'ai rassemblé mes 3 class en 1, modifiés les focntions et ca tourne. Thanks encore.