【问题标题】:Whats is proper way of using RowFilter on DataGridView populated with DataTable?在填充有 DataTable 的 DataGridView 上使用 RowFilter 的正确方法是什么?
【发布时间】:2020-01-24 09:15:32
【问题描述】:

我已经按照this SO post 的方法对datagridview 执行搜索

以下是我的尝试。我想在文本更改时停止使用 DgvSearch() 方法查询数据库,而是使用 RowFilter。

在当前尝试中,从 LoadDataParts() 正确填充了 datagridview,当我开始输入 TxtPP_GBC2 时,我只看到列标题,没有抛出异常。

GBC 列定义为“INT”。

预期结果 -> TxtPP_GBC2_TextChanged() 的行为与 DgvSearch() 相同

public partial class ProgramPart : Form
{
    public SqlConnection Con { get; } = new SqlConnection(@"***");
    public  string UserDBO;
    private DataTable dataTable = new DataTable();
    public ProgramPart()
    {
        InitializeComponent();
        LoadDataParts();
    }
    public void LoadDataParts()
    {
        string sql3 = "SELECT * FROM Parts";

        SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(sql3, Con);
        sqlDataAdapter.Fill(dataTable);
        sqlDataAdapter.Dispose();
        dataGridView1n.DataSource = dataTable;
    }

    private void TxtPP_GBC2_TextChanged(object sender, EventArgs e)
    {
        //DgvSearch(); //////// DgvSearch() works perferctly
        try
        {
            if(txtPP_GBC2.Text == "")
            {
                dataTable.Clear();
                LoadDataParts();
                dataGridView1n.Refresh();
                return;
            }
            (dataGridView1n.DataSource as DataTable).DefaultView.RowFilter = "GBC = '" + Convert.ToInt32(txtPP_GBC2.Text) + "'";
            dataGridView1n.Refresh();
        }
        catch(Exception s)
        {
            MessageBox.Show(s.ToString());
        }
    }

    private void DgvSearch()
    {
        string sql3 = "SELECT * FROM Parts WHERE GBC LIKE @GBC2 AND Description LIKE @DES";
        Con.Open();
        SqlDataAdapter da = new SqlDataAdapter(sql3, Con);
        da.SelectCommand.Parameters.AddWithValue("@GBC2", SqlDbType.Int).Value = "%" + txtPP_GBC2.Text + "%";
        da.SelectCommand.Parameters.AddWithValue("@DES", SqlDbType.VarChar).Value = "%" + txtPP_Description2.Text + "%";

        DataSet ds = new DataSet();
        da.Fill(ds, "Parts");
        da.Dispose();
        dataGridView1n.DataSource = ds;
        dataGridView1n.DataMember = "Parts";
        Con.Close();


  }
}

【问题讨论】:

  • 如果该列是 int,为什么要将它与字符串进行比较?也许您正在寻找 like this 的东西?
  • 你能提供工作示例@RezaAghaei 吗?
  • 哇;我敦促你重新考虑——将一个完整的数据库表加载到一个本地数据表中,这样你就可以搜索它们,除了最人为的小型数据集示例之外,这是一个相当糟糕的想法。数据库非常擅长搜索数据。 C# 数据表在搜索方面相对较差。将数百万条记录拖到网络上以便在本地进行搜索是一个糟糕的主意。也许考虑植入延迟,以便您仅在用户停止输入后 1 秒运行搜索,这样您就不会在每次按键时都进行搜索。 (称为去抖动)
  • @CaiusJard - 谢谢,我明白了。您建议我返回查询 SQL 但在查询之间实现延迟?
  • 是的,这就是我的建议 - 要么让用户按回车键等启动搜索,要么每次按下键时将计数器重置为 0,在 100 毫秒计时器上递增,并且仅当查询达到 10 等时启动查询

标签: c# .net winforms datagridview datatable


【解决方案1】:

您可以使用Convert 表达式函数将 int 列的值转换为字符串并使用此类过滤器进行比较:

private DataTable LoadData()
{
    var dt = new DataTable();
    dt.Columns.Add("C1", typeof(int));
    dt.Rows.Add(1);
    dt.Rows.Add(11);
    dt.Rows.Add(2);
    dt.Rows.Add(22);
    return dt;       
}
private void Form1_Load(object sender, EventArgs e)
{
    dataGridView1.DataSource = LoadData();
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
    var filter = "";
    if (!string.IsNullOrEmpty(textBox1.Text))
        filter = $"Convert([C1], System.String) = '{textBox1.Text}'";
    (dataGridView1.DataSource as DataTable).DefaultView.RowFilter = filter;
}

如果出于任何原因您更喜欢LIKE 运算符,则需要将过滤器更改为:

filter = $"Convert([C1], System.String) LIKE '%{textBox1.Text}%'";

【讨论】:

  • @KubaDo 您需要学习如何隔离问题以及如何调试代码。它在隔离的minimal reproducible example 中运行良好。我会将完整的代码添加到答案中。
  • 非常感谢,您的代码与 LIKE 运算符没有按预期工作,我已使用 DataView 类管理预期结果
  • 当您在答案中需要的唯一更改是将= 更改为LIKE(最初建议该评论)我会说这意味着答案正在工作。
猜你喜欢
  • 1970-01-01
  • 2012-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-05
  • 1970-01-01
  • 2014-01-26
相关资源
最近更新 更多