我正在C#Visual Studio 2010中開發用戶控件 - 一種用於過濾datagridview的「快速查找」文本框。它應該適用於3種類型的datagridview數據源:DataTable,DataBinding和DataSet。 我的問題是從DataSet對象中過濾DataTable,它顯示在DataGridView上。在不改變數據源的情況下過濾DataGridView
有可能爲3例(與DataGridView的文本框,並在其上的WinForm標準的應用實例) - 第2工作正常,我有問題,一個3:
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 = 「國家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());
}
- 雖然數據表上過濾(ds.Tables [0] .DefaultView.Count變化),datagridview的不更新...... 我去過:
代碼下面假裝這些操作尋找任何解決方案很長一段時間,但問題是,數據源不能更改 - 因爲它是額外的控制,我不希望它搞亂了程序員的代碼。
我知道可能的解決方案是:
- 使用數據綁定從數據集綁定數據表,並用它作爲例子2:但是它的代碼編寫過程中是由程序員,
- 改變的數據源的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的DataSource看到正在發生變化......
我不想這樣做,因爲這是可能的程序員編寫類似的代碼如下:
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
}
他可以這樣做,因爲他在設計器中使用DataSet和DataMember設計DataGridView。 代碼將被編譯,但是,使用過濾器後,它會拋出一個異常...
所以問題是:如何過濾DataSet中的DataTable並顯示DataGridView上的結果而不更改DataSource到另一個?爲什麼我可以直接從示例1過濾DataTable,而從DataSet過濾DataTable不起作用? 也許這不是DataTable在這種情況下綁定到DataGridView?
請注意,我的問題,從設計問題的重視,因此該解決方案必須工作在例如3
我除了所有寶貴的意見和方案2美分。這是一篇[文章](http://10tec.com/articles/datagridview-filter.aspx),它描述了以這種方式過濾數據綁定的DataGridView的優點和缺點,併爲您提供了一些更好的方法。 – TecMan 2015-02-19 16:35:25
不要重複,但我認爲我的建議不會每次都有效。事實上,有時我們的代碼不太可能會解除例外。試着用一個bindingSource進行過濾,你有機會做出好的代碼。像日期:bindingSource.Filter = string.Format ..... – 2017-04-17 12:13:05