在文本框上搜索内容后在 C# 中重新加载 gridview

Reload gridview in C# after searching something on textbox

所以我有一个 gridview 显示我的数据库中的一些订单,我想在有人在我必须搜索的文本框中搜索订单后刷新我的 gridview,但我不能这样做,因为我知道我正在这样做已经加载了 gridview。

CS

public void refreshdata()
        {
            SqlCommand cmd = new SqlCommand("select DISTINCT No_ from [Encomenda]", con);
            SqlDataAdapter sda = new SqlDataAdapter(cmd);
            DataTable dt = new DataTable();
            sda.Fill(dt);
            GridView1.DataSource = dt;
            GridView1.DataBind();
        }

         protected void btnsearch_Click(object sender, EventArgs e)
    {
        con.Open();


        SqlCommand cmd = new SqlCommand("select DISTINCT No_ from [encomenda] where No_= @No_", con);

        cmd.Parameters.AddWithValue("@No_", txtSearch.Value);


        cmd.ExecuteReader();

            SqlDataAdapter sda1 = new SqlDataAdapter(cmd);
            DataTable dt = new DataTable();
            sda1.Fill(dt);
            GridView1.DataSource = dt;
            GridView1.DataBind();

        con.Close();
    }

        protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
        {
            GridView1.PageIndex = e.NewPageIndex;
            refreshdata();
        }

你的 search button 上唯一的代码应该是这样的:

SqlCommand cmd = new SqlCommand("select DISTINCT No_ from [encomenda] where No_= @No_", con);
cmd.Parameters.AddWithValue("@No_", txtSearch.Value);

SqlDataAdapter sda = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
sda.Fill(dt);
GridView1.DataSource = dt;

这与加载数据的方式几乎相同,唯一的区别是您传递的查询 SqlCommand

此外,您已经在代码中使用了 DataAdapter,因此使用 DataReader 毫无用处。

读取器和适配器是执行查询的两种机制。你不应该同时使用两者。即使没有错误,您也会无缘无故地被 运行 查询两次。要仅使用适配器,请删除所有 reader 内容。适配器将自行打开和关闭连接。

And consider not using AddWithValue

protected void btnsearch_Click(object sender, EventArgs e)
{
    SqlCommand cmd = new SqlCommand("select DISTINCT No_ from [encomenda] where No_= @No_", con);

    cmd.Parameters.AddWithValue("@No_", txtSearch.Value);

    sqlDataAdapter sda1 = new SqlDataAdapter(cmd);
    DataTable dt = new DataTable();
    sda1.Fill(dt);
    GridView1.DataSource = dt;
    GridView1.DataBind();
}

我会考虑一个加载网格的例程,这样您只需编写一次该代码。

因此,您的代码可以如下所示:

    protected void Page_Load(object sender, EventArgs e)
    {
        if (IsPostBack == false)
        {
            LoadGrid();
        }
    }

    public void LoadGrid()
    {
        using (SqlCommand cmdSQL = new SqlCommand("SELECT * from tblHotels ",
            new SqlConnection(Properties.Settings.Default.TEST4)))
        {
            cmdSQL.Connection.Open();
            // now load grid
            if (txtCitySearch.Text != "")
            {
                cmdSQL.CommandText += "WHERE City = @City ";
                cmdSQL.Parameters.Add("@City", SqlDbType.NVarChar).Value = txtCitySearch.Text;
            }
            cmdSQL.CommandText += "ORDER BY HotelName";
            MyGrid.DataSource = cmdSQL.ExecuteReader();
            MyGrid.DataBind();
        }
    }

所以,如果您有那个搜索框和一个再次搜索的按钮,那么它看起来像这样:

   protected void Button1_Click(object sender, EventArgs e)
    {
        LoadGrid();
    }

因此,您可以将 sql 参数设置为“可选”,如上所示。

现在,请注意我将 reader 结果直接推入了网格。如果您使用数据绑定事件,您可能非常希望在数据 table 中 use/shove 因为在数据绑定期间我们经常希望使用绑定过程中使用的完整数据行。

例如:

 // get City from current data row source - set the drop to data row City
 MyDrop.SelectedValue = ((DataRowView)e.Row.DataItem)["City"].ToString();

现在我们如何使用DataItem。数据项仅在绑定过程中有效,但因此,我们经常使用它从绑定过程中实际使用的数据源中获取 data/rows/information(比如一些 PK 值未显示在网格中)。

如果您使用:

MyGrid.DataSource = cmdSQL.ExecuteReader();

然后你发现dataitem是错误的数据类型。因此,如果您“打算”使用 DataItem 并在绑定事件期间需要完整的数据行,那么如前所述,请使用:

DataTable rst = New Datatable();
rst.Load(cmdSQL.ExecuteReader());
MyGrid.DataSource = rst;

这样数据项就是一个正确类型的正确数据行,您可以在绑定过程中自由使用。加载网格后,当然 DataItem/Datasource 超出范围,不再存在。

但绑定期间的完整数据行源可用 - 但这意味着您最好使用数据table,而不是将“reader”结果直接发送到网格 WHEN在绑定过程中,您的代码需要完整的数据行和所有列。