Skip to content
Advertisement

Data selected from SQL database from top item in checkboxlist is copied to all Gridview rows

I am trying to create a grid view table where i want to show some selected data from a checkboxlist. THe problem is that whenever i select some data from the checkboxlist, the gridview will only show the data from the top checked box and not multiple different data tied to each box in the list even though i have checked multiple boxes to show data from?

Det gridview does add a new line when a new box is checked, however the new row copies the data from the previous row

Both the gridview and the checkboxlist are connected to the SQLdatabase, where the data comes from:

CODE

 public partial class Visual : System.Web.UI.Page
 {
    String con = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;

    protected void Page_Load(object sender, EventArgs e)
    {

    }

    public void CheckBoxList1_SelectedIndexChanged(object sender, EventArgs e)
    {
        DataTable dt = new DataTable();  
        DataRow dr = dt.NewRow();
        dt.Columns.Add("SensorID");
        dt.Columns.Add("BatteryLife");
        dt.Columns.Add("YearInUsage");
        dt.Columns.Add("NumberOfUsage");
        dt.Columns.Add("Occupations");
        dt.Columns.Add("Placement");
        dt.Columns.Add("Zip");
        dt.Columns.Add("City");

        List<DataListe> dl = new List<DataListe>();

        foreach (ListItem item in CheckBoxList1.Items) 
        {
            SqlConnection sc = new SqlConnection(con);
            sc.Open(); 
            SqlCommand cmd = new SqlCommand("SELECT * FROM Statistic WHERE SensorID='" + CheckBoxList1.SelectedValue + "'", sc); 
            SqlDataReader reader = cmd.ExecuteReader();

            if (item.Selected) 
            {
                while (reader.Read()) 
                {
                    DataListe dali = new DataListe();

                    string si = (string)reader["SensorID"];
                    dali.SensorID = si;

                    string bl = (string)reader["BatteryLife"];
                    dali.BatteryLife = bl;

                    string yu = (string)reader["YearInUsage"];
                    dali.YearInUsage = yu;

                    int nu = (int)reader["NumberOfUsage"];
                    dali.NumberOfUsage = nu;

                    string oc = (string)reader["Occupations"];
                    dali.Occupations = oc;

                    string pl = (string)reader["Placement"];
                    dali.Placement = pl;

                    int zi = (int)reader["Zip"];
                    dali.Zip = zi;

                    string ci = (string)reader["City"];
                    dali.City = ci;


                    dl.Add(dali); 

                }
            }
            sc.Close(); 
        }

        GridView1.DataSourceID = null; 
        GridView1.DataSource = dl;
        GridView1.DataBind();

        return;
}

I expected that the gridview add a new row when a new box in checkboxlist is checked,and keep the previous row intact. The row should contain the information tied to the item in the checkboxlist, which is provided by the SQLdatabase.

However, the gridview does add a new row, when a new box is checked, but it copies the data from the already displayed row.

Advertisement

Answer

The problem in your code is that you use the CheckboxList1.SelectedValue. What should be the SelectedValue of a CheckBoxList? Do you suppose that whatever this value is, it will change while you loop over the Items collection?

You need to use Item.Value instead

// Opening the connection just one time before starting the loop
using(SqlConnection sc = new SqlConnection(con))
{
    sc.Open(); 
    string cmdText = "SELECT * FROM Statistic WHERE SensorID=@id";
    foreach (ListItem item in CheckBoxList1.Items) 
    {
        if (item.Selected) 
        {
            // Moved the actual query inside the check for the item.Selected
            // so you are calling the db only for the items that you want to use
           SqlCommand cmd = new SqlCommand(cmdText, sc); 
           cmd.Parameters.Add("@id", SqlDbType.NVarChar).Value = item.Value;
           using(SqlDataReader reader = cmd.ExecuteReader())
           {
               while (reader.Read()) 
               {
                   DataListe dali = new DataListe();
                   dali.SensorID = (string)reader["SensorID"];
                   dali.BatteryLife = (string)reader["BatteryLife"];
                   dali.YearInUsage = (string)reader["YearInUsage"];
                   dali.NumberOfUsage = (int)reader["NumberOfUsage"];
                   dali.Occupations = (string)reader["Occupations"];
                   dali.Placement = (string)reader["Placement"];
                   dali.Zip = (int)reader["Zip"];
                   dali.City = (string)reader["City"];
                   dl.Add(dali); 
             }
        } // At this point the reader is closed and disposed by the ending using block
    }
}  // At this point the connection is closed and disposed by the ending using block

Other points to note: Disposable objects like connection and reader should be disposed when you don’t need them anymore. The using statement ensure this even in case of excepions. Another point very important is the use of parameters when you want to pass a query text to your database engine. Concatenating string together is a sure way to find yourself in troubles with Sql Injection and possible parsing errors.

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement