mj8*_*j82 89 c# datagridview filter visual-studio-2010 winforms
我正在使用C#Visual Studio 2010开发用户控件 - 一种用于过滤datagridview的"快速查找"文本框.它应该适用于3种类型的datagridview数据源:DataTable,DataBinding和DataSet.我的问题是从DataSet对象过滤DataTable,它显示在DataGridView上.
可能有3个案例(标准WinForm应用程序的示例,其中包含DataGridView和TextBox) - 前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());
}
Run Code Online (Sandbox Code Playgroud)
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());
}
Run Code Online (Sandbox Code Playgroud)
3. datagridview.DataSource = dataSource; datagridview.DataMember ="TableName":它不起作用
当您使用designer设计表时会发生这种情况:将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());
}
Run Code Online (Sandbox Code Playgroud)
如果你测试它 - 虽然数据表被过滤(ds.Tables [0] .DefaultView.Count更改),datagridview没有更新...我一直在寻找任何解决方案很长时间,但问题是DataSource不能改变 - 因为它是额外的控制,我不希望它搞乱程序员的代码.
我知道可能的解决方案是:
- 使用DataBinding从DataSet绑定DataTable并将其用作示例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());
}
Run Code Online (Sandbox Code Playgroud)
是不可接受的,正如你在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
}
Run Code Online (Sandbox Code Playgroud)
他可以这样做,因为他在设计器中使用DataSet和DataMember设计了DataGridView.代码将被编译,但是,在使用过滤器后,它将抛出异常...
所以问题是:如何在DataSet中过滤DataTable并在DataGridView上显示结果而不将DataSource更改为另一个?为什么我可以直接从示例1过滤DataTable,而从DataSet过滤DataTable不起作用?在这种情况下,可能不是DataTable绑定到DataGridView?
请注意,我的问题来自设计问题,因此解决方案必须在示例3中工作.
Bra*_*uce 131
我只花了一个小时来处理类似的问题.对我来说,答案结果是令人尴尬的简单.
(dataGridViewFields.DataSource as DataTable).DefaultView.RowFilter = string.Format("Field = '{0}'", textBoxFilter.Text);
Run Code Online (Sandbox Code Playgroud)
Joe*_*isk 20
我开发了一个通用语句来应用过滤器:
string rowFilter = string.Format("[{0}] = '{1}'", columnName, filterValue);
(myDataGridView.DataSource as DataTable).DefaultView.RowFilter = rowFilter;
Run Code Online (Sandbox Code Playgroud)
方括号允许列名称中的空格.
此外,如果要在过滤器中包含多个值,可以为每个附加值添加以下行:
rowFilter += string.Format(" OR [{0}] = '{1}'", columnName, additionalFilterValue);
Run Code Online (Sandbox Code Playgroud)
小智 7
一种更简单的方法是横向数据,并使用Visible
属性隐藏线条.
// Prevent exception when hiding rows out of view
CurrencyManager currencyManager = (CurrencyManager)BindingContext[dataGridView3.DataSource];
currencyManager.SuspendBinding();
// Show all lines
for (int u = 0; u < dataGridView3.RowCount; u++)
{
dataGridView3.Rows[u].Visible = true;
x++;
}
// Hide the ones that you want with the filter you want.
for (int u = 0; u < dataGridView3.RowCount; u++)
{
if (dataGridView3.Rows[u].Cells[4].Value == "The filter string")
{
dataGridView3.Rows[u].Visible = true;
}
else
{
dataGridView3.Rows[u].Visible = false;
}
}
// Resume data grid view binding
currencyManager.ResumeBinding();
Run Code Online (Sandbox Code Playgroud)
只是一个想法...它对我有用.
归档时间: |
|
查看次数: |
286159 次 |
最近记录: |