Я разрабатываю пользовательский элемент управления в C # Visual Studio 2010 - своего рода текстовое поле «быстрого поиска» для фильтрации представления данных.Он должен работать для 3 типов источников данных в виде сетки: DataTable, DataBinding и DataSet.Моя проблема с фильтрацией DataTable из объекта DataSet, который отображается в DataGridView.
Может быть 3 случая (примеры для стандартного приложения WinForm с DataGridView и TextBox на нем) - первые 2 работают нормально, япроблема с третьим:
1.datagridview.DataSource = dataTable: он работает
, поэтому я могу фильтровать, задав: dataTable.DefaultView.RowFilter = "country 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, "Switzerland" });
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: он работает
, поэтому я могу фильтровать, установив: bindingSource.Filter = "country 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, "Switzerland" });
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": это не работает
Это происходит, когда вы проектируете таблицу с помощью конструктора: поместите DataSet из набора инструментов в форму, добавьте к нему dataTable, а затем установите datagridview.DataSource = dataSource;и datagridview.DataMember = "TableName".
Приведенный ниже код делает вид, что эти операции:
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, "Switzerland" });
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());
}
Если вы проверяете его - хотя datTables [0] .DefaultView.Count изменяется,datagridview не обновляется ... Я долго искал какое-либо решение, но проблема в том, что DataSource не может изменить - так как это дополнительный элемент управления, я не хочу, чтобы с ним связывалиськод программиста
Я знаю, что возможны следующие решения:
- связать DataTable из DataSet с использованием DataBinding и использовать его как пример 2: но это зависит от программиста во время написания кода,
- изменить dataSource на BindingSource,dataGridView.DataSource = dataSet.Tables [0] или для DefaultView программно: однако это изменяет DataSource.Таким образом, решение:
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());
}
неприемлемо, поскольку вы видите, что источник данных MessageBox меняется ...
Я не хочу этого делать, потому что программист может написать кодпримерно так:
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
}
Он может сделать это, так как он разработал DataGridView с DataSet и DataMember в конструкторе.Код будет скомпилирован, однако после использования фильтра он выдаст исключение ...
Итак, вопрос: как я могу отфильтровать DataTable в DataSet и показать результаты в DataGridView, не меняя DataSource на другой?Почему я могу напрямую фильтровать DataTable из примера 1, в то время как фильтрация DataTable из DataSet не работает?Может быть, это не DataTable, привязанный к DataGridView в этом случае?
Обратите внимание, что моя проблема связана с проблемами проектирования, поэтому решение ДОЛЖНО РАБОТАТЬ на примере 3.