过滤DataGridView而不改变数据源 [英] Filtering DataGridView without changing datasource

查看:149
本文介绍了过滤DataGridView而不改变数据源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在C#Visual Studio 2010中开发用户控件 - 一种用于过滤datagridview的快速查找文本框。它应该适用于3种datagridview数据源:DataTable,DataBinding和DataSet。
我的问题是从DataSet对象过滤DataTable,它显示在DataGridView上。

I'm developing user control in C# Visual Studio 2010 - a kind of "quick find" textbox for filtering datagridview. It should work for 3 types of datagridview datasources: DataTable, DataBinding and DataSet. My problem is with filtering DataTable from DataSet object, which is displayed on DataGridView.

可能有3种情况(标准WinForm应用程序与DataGridView和TextBox的示例在上面) - 前2个工作正常,我有第三个问题:

There could be 3 cases (examples for standard WinForm application with DataGridView and TextBox on it) - first 2 are working OK, I've problem with 3rd one:

1。 datagridview.DataSource = dataTable:它的工作原理

所以我可以通过设置过滤:dataTable.DefaultView.RowFilter =country LIKE'%s%';

1. datagridview.DataSource = dataTable : it works
so I can filter by setting: 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%';

2. datagridview.DataSource = bindingSource: it works
so I can filter by setting: 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。

以下代码假装这些操作:

3. datagridview.DataSource = dataSource; datagridview.DataMember = "TableName": it doesn't work
It happens when you design a table using designer: put the DataSet from toolbox on form, add dataTable to it and then set datagridview.DataSource = dataSource; and datagridview.DataMember = "TableName".
Code below pretends these operations:

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());
}

如果你测试它 - 虽然datatable被过滤(ds.Tables [0] .DefaultView.Count更改),datagridview不更新...
我一直在寻找很长时间的任何解决方案,但问题是, DataSource无法更改 - 因为它是额外的控制,我不想让它弄乱程序员的代码。

If you test it - although datatable is filtered (ds.Tables[0].DefaultView.Count changes), datagridview is not updated... I've been looking for a long time for any solution, but the problem is that DataSource cannot change - as it's additional control, I don't want it to mess up with programmer's code.

我知道可能的解决方案是:

- 使用DataBinding从DataSet绑定DataTable,并将其用作示例2:但是由程序员在代码写入,

- 将dataSource更改为BindingSource,dataGridView.DataSource = dataSet.Tables [0]或以DefaultView方式更改:但是,它会更改DataSource。所以解决方案:

I know possible solutions are:
- to bind DataTable from DataSet using DataBinding and use it as example 2: but it's up to the programmer during code writing,
- to change dataSource to BindingSource, dataGridView.DataSource = dataSet.Tables[0], or to DefaultView programatically: however, it changes the DataSource. So the 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());
}

是不可接受的,正如你在MessageBox的dataSource上看到的一样...

is not acceptable, as you see on MessageBox's dataSource is changing...

我不想这样做,因为程序员可以编写类似于以下代码:

I don't want to do that, because it's possible a programmer writes code similar to this:

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
}



代码将被编译,但使用过滤器后会引发异常...

He can do that, as he designed DataGridView with DataSet and DataMember in designer. Code will be compiled, however, after using a filter, it will throw an exception...

所以问题是:如何过滤DataTable DataSet并在DataGridView上显示结果,而不将DataSource更改为另一个?为什么我可以直接从示例1过滤DataTable,而从DataSet过滤DataTable不起作用?
也许在这种情况下,DataTable不会绑定到DataGridView?

So the question is: how can I filter DataTable in DataSet and show the results on DataGridView without changing DataSource to another? Why I can filter DataTable from example 1 directly, while filtering DataTable from DataSet is not working? Maybe it's not DataTable bound to DataGridView in that case?

请注意,我的问题来自于设计问题,所以解决方案必须在示例3上工作。

Please note, that my problem takes from designing issues, so the solution MUST WORK on example 3.

推荐答案

我刚刚花了一个小时就遇到了类似的问题。对我来说,答案很简单。

I just spent an hour on a similar problem. For me the answer turned out to be embarrassingly simple.

(dataGridViewFields.DataSource as DataTable).DefaultView.RowFilter = string.Format("Field = '{0}'", textBoxFilter.Text);

这篇关于过滤DataGridView而不改变数据源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆