C# - 如何在没有BindingSource的情况下在DataGridView中搜索和过滤

时间:2016-09-10 10:28:47

标签: c# search datagridview filter sqlite

我想在 C# SQLite 中搜索数据网格视图,但我没有绑定Datagridview的来源。我用以下代码填充Datagridview:

SQLiteConnection conn = new SQLiteConnection("Data Source=gasstation.sqlite;Version=3");

dt = new DataTable();
SQLiteCommand cmd = new SQLiteCommand("SELECT ID,fname, lname, nationalCode," + 
      personalCode, phone ,address, datetime(dateEnter) as dateEnter FROM Workers", conn);
conn.Open();
SQLiteDataAdapter da = new SQLiteDataAdapter(cmd);

da.Fill(dt);               

SQLiteDataReader read = cmd.ExecuteReader();
DateTime date;
PersianCalendar pc = new PersianCalendar();                
while (read.Read())
{
    date = read.GetDateTime(7);
    string datePC = string.Format("{0}/{1}/{2}", pc.GetYear(date), 
                                  pc.GetMonth(date), pc.GetDayOfMonth(date));

    dgvUsers.Rows.Add(new object[] { 
        read.GetValue(0),
        read.GetValue(1),
        read.GetValue(2),
        read.GetValue(3),
        read.GetValue(4),
        read.GetValue(5),
        read.GetValue(6),
        datePC   });
    }
    read.Close();
    conn.Close();
}

如何使用文本框的文本更改事件对数据网格视图进行搜索和过滤。

我在StackOverflow中看到了所有问题和答案,但它并没有正确回答我的问题。

1 个答案:

答案 0 :(得分:1)

你的代码有点困惑。

首先您将所有数据填入DataTable DataAdapter,看起来不错。但然后您在DataReader中再次 并将其填入代码中的DataGridView

这不是必需的。忘记读者及其所处的循环!

如果DataTable包含数据,您可以将DGV绑定到该表:

dgvUsers.DataSource = dt;

直接绑定时,您无法排序或过滤。因此,最好创建一个BindingSource并将其设为DGV' DataSource

BindingSource bs = new BindingSource(dt, "");

注意第二个参数:它是空的,因为我们使用单个表作为BindingSource的数据源。如果我们使用DataSet,我们会将TableName放在那里。您没有设置TableName属性;最好这样做,所以让我们将实例化更改为dt = new DataTable("someTableName");

现在我们可以通过DGV

BindingSource绑定到数据了
dgvUsers.DataSource = bs;

最后,我们可以根据需要设置SortFilter属性。

从其他控制中我们可以回到BindingSource,也许是这样:

private void textBox_lastName_TextChanged(object sender, EventArgs e)
{
    BindingSource bs = dgvUsers.DataSource as BindingSource;

    if (textBox_lastName.Text == "") bs.RemoveFilter(); 
    else bs.Filter =  "lname like '%" +  textBox_lastName.Text + "%'";
}

我注意到在循环中你正在创建一个格式化的日期字段。我怀疑这是首先创建循环的原因..?但您也可以将其添加到DataTable;最好的方法当然是,一如既往地选择你想要的价值,让DBMS完成所有的工作。

但是如果你想做非常特别的事情,你不相信SQL函数可以实现,就像使用PersianCalendar类一样,你可以添加一个虚拟字段给你的SELECT

   SQLiteCommand cmd = new SQLiteCommand("SELECT ID,fname, lname ,nationalCode, " + 
      "personalCode, phone, address, datetime(dateEnter) as dateEnter " + 
      "\"\" as pcDate FROM Workers", conn);

..并在填充表后填充具有特殊值的虚拟字段:

DateTime date;
PersianCalendar pc = new PersianCalendar();

foreach(DataRow row in dt.Rows)
{
   date = row.Field<DateTime>("dateEnter");
   string datePC = string.Format("{0}/{1}/{2}", 
                   pc.GetYear(date), pc.GetMonth(date), pc.GetDayOfMonth(date));
   row.SetField<string>("pcDate", datePC);
}

您现在可能想隐藏DVG中的dateEnter列:

dgvUsers.Columns["dateEnter"].Visible = false;