Je suis le développement de contrôle de l'utilisateur en C#, Visual Studio 2010 - une sorte de "recherche rapide" zone de texte pour le filtrage datagridview. Il doit travailler pour 3 types de datagridview sources de données: DataTable, liaison de données et l'ensemble de données. Mon problème est avec le filtrage DataTable d'objet DataSet, qui est affiché sur le DataGridView.
Il pourrait y avoir 3 cas (exemples standard, l'application WinForm avec DataGridView et de la zone de texte) - les 2 premiers sont de travail OK, j'ai problème avec le 3ème:
1. datagridview.DataSource = dataTable : il fonctionne
donc, je peux filtrer par paramètre: dataTable.DefaultView.RowFilter = "pays LIKE '%s%'";
DataTable dt = new DataTable();
private void Form1_Load(object sender, EventArgs e)
{
dt.Columns.Add("id", typeof(int));
dt.Columns.Add("country", typeof(string));
dt.Rows.Add(new object[] { 1, "Belgium" });
dt.Rows.Add(new object[] { 2, "France" });
dt.Rows.Add(new object[] { 3, "Germany" });
dt.Rows.Add(new object[] { 4, "Spain" });
dt.Rows.Add(new object[] { 5, "Swiss" });
dt.Rows.Add(new object[] { 6, "United Kingdom" });
dataGridView1.DataSource = dt;
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
MessageBox.Show("DataSource type BEFORE = " + dataGridView1.DataSource.GetType().ToString());
dt.DefaultView.RowFilter = string.Format("country LIKE '%{0}%'", textBox1.Text);
MessageBox.Show("DataSource type AFTER = " + dataGridView1.DataSource.GetType().ToString());
}
2. datagridview.DataSource = bindingSource: il fonctionne
donc, je peux filtrer par paramètre: bindingSource.Filtre = "pays LIKE '%s%'";
DataTable dt = new DataTable();
BindingSource bs = new BindingSource();
private void Form1_Load(object sender, EventArgs e)
{
dt.Columns.Add("id", typeof(int));
dt.Columns.Add("country", typeof(string));
dt.Rows.Add(new object[] { 1, "Belgium" });
dt.Rows.Add(new object[] { 2, "France" });
dt.Rows.Add(new object[] { 3, "Germany" });
dt.Rows.Add(new object[] { 4, "Spain" });
dt.Rows.Add(new object[] { 5, "Swiss" });
dt.Rows.Add(new object[] { 6, "United Kingdom" });
bs.DataSource = dt;
dataGridView1.DataSource = bs;
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
MessageBox.Show("DataSource type BEFORE = " + dataGridView1.DataSource.GetType().ToString());
bs.Filter = string.Format("country LIKE '%{0}%'", textBox1.Text);
MessageBox.Show("DataSource type AFTER = " + dataGridView1.DataSource.GetType().ToString());
}
3. datagridview.DataSource = dataSource; datagridview.DataMember = "TableName": ça ne marche pas
Il arrive lors de la conception d'un tableau à l'aide de designer: mettre l'ensemble de données de la boîte à outils sur le formulaire, ajouter dataTable, puis définissez datagridview.DataSource = source de données; et datagridview.DataMember = "TableName".
Le Code ci-dessous prétend que ces opérations:
DataSet ds = new DataSet();
DataTable dt = new DataTable();
private void Form1_Load(object sender, EventArgs e)
{
dt.Columns.Add("id", typeof(int));
dt.Columns.Add("country", typeof(string));
dt.Rows.Add(new object[] { 1, "Belgium" });
dt.Rows.Add(new object[] { 2, "France" });
dt.Rows.Add(new object[] { 3, "Germany" });
dt.Rows.Add(new object[] { 4, "Spain" });
dt.Rows.Add(new object[] { 5, "Swiss" });
dt.Rows.Add(new object[] { 6, "United Kingdom" });
ds.Tables.Add(dt);
dataGridView1.DataSource = ds;
dataGridView1.DataMember = dt.TableName;
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
MessageBox.Show("DataSource type BEFORE = " + dataGridView1.DataSource.GetType().ToString());
//it is not working
ds.Tables[0].DefaultView.RowFilter = string.Format("country LIKE '%{0}%'", textBox1.Text);
MessageBox.Show("DataSource type AFTER = " + dataGridView1.DataSource.GetType().ToString());
}
Si vous testez - le, bien que datatable est filtré (ds.Tables[0].DefaultView.Compte les modifications), datagridview n'est pas mis à jour... J'ai été à la recherche pour une longue période, pour toute solution, mais le problème est que la source de données ne peut pas changer comme ça d'un contrôle supplémentaire, je n'en veux pas à gâcher avec du programmeur code.
Je sais que les solutions possibles sont:
- pour lier Table de données, en utilisant la liaison de données et l'utiliser comme exemple 2: mais c'est pour le programmeur lors de l'écriture de code,
- pour changer la source de données à BindingSource, dataGridView.DataSource = dataSet.Tables[0], ou à DefaultView par programmation: toutefois, il change la source de données. Donc la solution:
private void textBox1_TextChanged(object sender, EventArgs e)
{
MessageBox.Show("DataSource type BEFORE = " + dataGridView1.DataSource.GetType().ToString(), ds.Tables[0].DefaultView.Count.ToString());
DataView dv = ds.Tables[0].DefaultView;
dv.RowFilter = string.Format("country LIKE '%{0}%'", textBox1.Text);
dataGridView1.DataSource = dv;
MessageBox.Show("DataSource type AFTER = " + dataGridView1.DataSource.GetType().ToString(), ds.Tables[0].DefaultView.Count.ToString());
}
n'est pas acceptable, comme vous le voyez sur MessegeBox es la source de données est en train de changer...
Je ne veux pas le faire, car il est possible progemmer écrire du code similaire à ceci:
private void textBox1_TextChanged(object sender, EventArgs e)
{
MessageBox.Show("DataSource type BEFORE = " + dataGridView1.DataSource.GetType().ToString(), ds.Tables[0].DefaultView.Count.ToString());
DataSet dsTmp = (DataSet)(dataGridView1.DataSource); //<--- it is OK
DataView dv = ds.Tables[0].DefaultView;
dv.RowFilter = string.Format("country LIKE '%{0}%'", textBox1.Text);
dataGridView1.DataSource = dv; //<--- here the source is changeing from DataSet to DataView
MessageBox.Show("DataSource type AFTER = " + dataGridView1.DataSource.GetType().ToString(), ds.Tables[0].DefaultView.Count.ToString());
dsTmp = (DataSet)(dataGridView1.DataSource); //<-- throws an exception: Unable to cast object DataView to DataSet
}
Il peut le faire, comme il l'a conçu DataGridView avec DataSet et DataMember dans designer. Le Code sera compilé, howewer, après l'aide d'un filtre, qu'il va jeter un excepcion...
La question est donc: comment puis-je filtrer DataTable dans le jeu de données et afficher les résultats sur DataGridView sans changer la source de données à un autre? Pourquoi je ne peux filtrer DataTable à partir de l'exemple 1 directement, tout en filtrant la Table de jeu de données ne fonctionne pas? C'est peut-être pas DataTable liées à la DataGridView dans ce cas?
Veuillez noter, que mon problème prend de la conception, de sorte que la solution DOIT TRAVAILLER sur l'exemple 3.