Dynamically add headers and columns to GridView - c#

I have a gridview but currently it only sets one header. What I want it to do is add new header beside the other columns at the end of the table based on the number of users.
protected void GridView1_RowDataBound(object sender, System.Web.UI.WebControls.GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Header)
{
GridView1.UseAccessibleHeader = true;
GridView1.AutoGenerateColumns = false;
int i = 6;
string constr = ConfigurationManager.ConnectionStrings["CMT"].ConnectionString;
using (SqlConnection conn = new SqlConnection(constr))
{
using (SqlCommand cmd = new SqlCommand())
{
cmd.CommandText = "SELECT * FROM [user]";
cmd.Connection = conn;
conn.Open();
using (SqlDataReader sdr = cmd.ExecuteReader())
{
while (sdr.Read())
{
GridView1.Columns[6].HeaderText = sdr["user_first_name"].ToString();
break;
}
}
conn.Close();
}
}
}
}

You can add TemplateField columns to the GridView before binding the data. It could be done in the Page_Load event handler:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
using (SqlConnection conn = new SqlConnection(constr))
{
using (SqlCommand cmd = new SqlCommand())
{
cmd.CommandText = "SELECT * FROM [user]";
cmd.Connection = conn;
conn.Open();
using (SqlDataReader sdr = cmd.ExecuteReader())
{
while (sdr.Read())
{
TemplateField field = new TemplateField();
field.HeaderText = sdr["user_first_name"].ToString();
field.HeaderStyle.Width = Unit.Pixel(80);
GridView1.Columns.Add(field);
}
}
conn.Close();
}
}
}
}

Related

Cannot set the SelectedValue in a ListControl with an empty ValueMember in winform using c#

I have a combobox that loads data from database but i got an error that you cannot set the selectedValue in a ListControl Although i have set the selectValue to a Primary key of a Table. But still getting error on runtime.. Here is the Code..
private void FormAddStudent_Load(object sender, EventArgs e)
{
//For combobox Campuse
cBoxCampus.DataSource = GetAllCampuses();
cBoxCampus.DisplayMember = "campus_name";
cBoxCampus.SelectedValue = "campus_id";
//Foe ComboBox Department
cBoxDepartment.DataSource = GetAllDepartment();
cBoxDepartment.DisplayMember = "depname";
cBoxDepartment.SelectedValue = "depid";
}
and this is the code behind Insert Button
private void btnInsert_Click(object sender, EventArgs e)
{
string CS = ConfigurationManager.ConnectionStrings["UMSdbConnectionString"].ConnectionString;
using (SqlConnection con = new SqlConnection(CS))
{
con.Open();
SqlCommand cmd = new SqlCommand("SELECT ISNULL(MAX(std_id),0)+1 FROM Student", con);
cmd.CommandType = CommandType.Text;
tbID.Text = cmd.ExecuteScalar().ToString();
{
using (SqlCommand cmd1 = new SqlCommand("INSERT INTO Student (std_id,std_name,std_f_name,std_mob,std_gender,std_cnic,std_campus,std_dep,std_address,std_batch,std_batch_year)VALUES(#std_id,#std_name,#std_f_name,#std_mob,#std_gender,#std_cnic,#std_campus,#std_dep,#std_address,#std_batch,#std_batch_year)VALUES(#campus_id,#campus_name)", con))
{
cmd1.CommandType = CommandType.Text;
cmd1.Parameters.AddWithValue("#std_id", tbID.Text);
cmd1.Parameters.AddWithValue("#std_name", tbName.Text);
cmd1.Parameters.AddWithValue("#std_f_name", tbFatherName.Text);
cmd1.Parameters.AddWithValue("#std_mob", tbMobNumber.Text);
cmd1.Parameters.AddWithValue("#std_gender", GetGender());
cmd1.Parameters.AddWithValue("#std_cnic", tbMobNumber.Text);
cmd1.Parameters.AddWithValue("#std_campus",(cBoxCampus.SelectedIndex == -1) ? 0: cBoxCampus.SelectedValue);
cmd1.Parameters.AddWithValue("#std_dep", (cBoxDepartment.SelectedIndex == -1) ? 0 : cBoxDepartment.SelectedValue);
cmd1.Parameters.AddWithValue("#std_address", tbAddress.Text);
cmd1.Parameters.AddWithValue("#std_batch", tbBatchNo.Text);
cmd1.Parameters.AddWithValue("#std_batch_year", tbBatchYear.Text);
cmd1.ExecuteNonQuery();
con.Close();
MessageBox.Show("Record Saved");
}
}
}
}
Replace
cBoxCampus.SelectedValue = "campus_id";
With ListControl.ValueMember Property
cBoxCampus.ValueMember = "campus_id";
Do similar operation for cBoxDepartment

How to remove subcategory in recursive function? asp.net

I am trying to delete subcategory from repeater using a link button. Currently, main category deleted but i cant delete subcaegory. Help me please...
private void BindRepeater()
{
DataTable dtCategory = system.GetDataTable("Select * from TBLCATEGORIES where SubCategoryID="+CategoryID);
if (dtCategory.Rows.Count > 0)
{
rpCategory.DataSource = dtCategory;
rpCategory.DataBind();
}
}
protected void OnDelete(object sender, EventArgs e)
{
//Find the reference of the Repeater Item.
RepeaterItem item = (sender as LinkButton).Parent as RepeaterItem;
string constr = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
using (SqlConnection con = new SqlConnection(constr))
{
SqlCommand cmd = new SqlCommand("Delete from TBLCATEGORIES where SubCategoryID="+CategoryID);
{
cmd.Connection = con;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
DeleteMsg.Visible = true;
}
}
this.BindRepeater();
}
Please find the code,hope this will help you:
protected void rpCategory_ItemCommand(object source, RepeaterCommandEventArgs e)
{
SqlConnection conn;
SqlCommand comm;
string connectionString = ConfigurationManager.ConnectionStrings["ShqiptarConnectionString"].ConnectionString;
conn = new SqlConnection(connectionString);
conn.Open();
if (e.CommandName == "Delete")
{
comm = new SqlCommand("Delete from TBLCATEGORIES where CategoryID=" + e.CommandArgument, conn);
comm.ExecuteNonQuery();
}
conn.Close();
conn.Dispose();
DeleteMsg.Visible = true;
//Rebind here: this.BindRepeater();
}

datagridview in webform c# show query in footer

I have two query's in C# running in a datagridview, one is to show all data. the other is set to display in the footer. The footer is showing, just not displaying my query.
query one (with footer)
protected void Button2_Click(object sender, EventArgs e)
{
MySqlCommand cmd = new MySqlCommand("SELECT * FROM Customer", cs);
cs.Open();
MySqlDataReader dgl = cmd.ExecuteReader();
dg.ShowFooter = true;
dg.DataSource = dgl;
dg.DataBind();
cs.Close();
}
**query two(footer query)**
protected void dg_DataBound(object sender, EventArgs e)
{
MySqlCommand cmd = new MySqlCommand("SELECT SUM(Donation) AS Total_Donation FROM Customer", cs);
cs.Open();
String totalDonations = Convert.ToString(cmd.ExecuteScalar());
cs.Close();
dg.FooterRow.Cells[3].Text = totalDonations;
}
the datagrid shows query one works well, the footer even shows but it has not got any data.
Although you have it working, there are ways to improve it.
In the first method, using statement would manage the connection better:
protected void Button2_Click(object sender, EventArgs e)
{
DataTable dt = new DataTable();
//Assuming you have a connection string strConnect
using (SqlConnection con = new SqlConnection(strConnect))
{
con.Open();
using (SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM Customer", con))
{
da.Fill(dt);
}
}
dg.ShowFooter = true;
dg.DataSource = dt;
dg.DataBind();
}
And the second method:
protected void dg_DataBound(object sender, EventArgs e)
{
String totalDonations = string.Empty;
//Assuming you have a connection string strConnect
using (SqlConnection con = new SqlConnection(strConnect))
{
con.Open();
using (SqlCommand cmd = new SqlCommand("SELECT SUM(Donation) AS Total_Donation FROM Customer", con))
{
totalDonations = Convert.ToString(cmd.ExecuteScalar());
}
}
dg.FooterRow.Cells[3].Text = totalDonations;
}
Probably I would use GridView's RowDataBound to write into footer where I can can know the type of row:
protected void dg_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Footer)
{
String totalDonations = string.Empty;
//Assuming you have a connection string strConnect
using (SqlConnection con = new SqlConnection(strConnect))
{
con.Open();
using (SqlCommand cmd = new SqlCommand("SELECT SUM(Donation) AS Total_Donation FROM Customer", con))
{
totalDonations = Convert.ToString(cmd.ExecuteScalar());
}
}
e.Row.Cells[3].Text = totalDonations;
}
}
EDIT : Here's the markup I have used to test:
<asp:GridView ID="dg" runat="server" AutoGenerateColumns="true" OnDataBound="dg_DataBound" ShowFooter="true">
</asp:GridView>
After hours of problems, I have solved it.
corrected code
{
MySqlCommand cmd = new MySqlCommand("SELECT * FROM Customer", cs);
MySqlCommand cmdtwo = new MySqlCommand("SELECT SUM(Donation) AS Total_Donation FROM Customer", cs);
cs.Open();
MySqlDataReader dgl = cmd.ExecuteReader();
dg.DataSource = dgl;
dg.ShowFooter = true;
dg.DataBind();
cs.Close();
cs.Open();
string totalDonations = Convert.ToString(cmdtwo.ExecuteScalar());
cs.Close();
dg.FooterRow.Cells[7].Text = "Total £";
dg.FooterRow.Cells[8].Text = totalDonations;
}
although I am sure there is a better way of doing this, if you know please feel free to edit.

Best Practice with object creation and data access

I've got a TabContainer control which houses several tabs. Depending on the ActiveIndex property of the TabContainer I would like for a button click to create a Gridview in that tab and bind it to a stored procedure. Currently, the following code works, but there's a lot of code repeated
protected void btnMakeGridView_Click(object sender, EventArgs e)
{
string cs = ConfigurationManager.ConnectionStrings["dbcs"].ConnectionString;
if (TabContainer1.ActiveTabIndex == 0)
{
using (SqlConnection con = new SqlConnection(cs))
{
using (SqlCommand cmd = new SqlCommand("spTest0", con))
{
con.Open();
cmd.CommandType = CommandType.Text;
SqlDataReader rdr = cmd.ExecuteReader();
GridView gv = new GridView();
TabContainer1.Tabs[TabContainer1.ActiveTabIndex].Controls.Add(gv);
gv.DataSource = rdr;
gv.DataBind();
}
}
}
else if (TabContainer1.ActiveTabIndex == 1)
{
using (SqlConnection con = new SqlConnection(cs))
{
using (SqlCommand cmd = new SqlCommand("spTest1", con))
{
con.Open();
cmd.CommandType = CommandType.Text;
SqlDataReader rdr = cmd.ExecuteReader();
GridView gv = new GridView();
TabContainer1.Tabs[TabContainer1.ActiveTabIndex].Controls.Add(gv);
gv.DataSource = rdr;
gv.DataBind();
}
}
}
else if (TabContainer1.ActiveTabIndex == 2)
{
using (SqlConnection con = new SqlConnection(cs))
{
using (SqlCommand cmd = new SqlCommand("spTest2", con))
{
con.Open();
cmd.CommandType = CommandType.Text;
SqlDataReader rdr = cmd.ExecuteReader();
GridView gv = new GridView();
TabContainer1.Tabs[TabContainer1.ActiveTabIndex].Controls.Add(gv);
gv.DataSource = rdr;
gv.DataBind();
}
}
}
else
{
Label1.Text = "You must select a tab to create the GridView in";
}
}
As you can see depending on the ActiveIndex of the TabContainer, a different stored procedure should be created inside each TabPanel. In my example I'm only working with one database so I don't have to worry about passing the connection string as a parameter for a database to connect to. At first blush I had added something like
//pass in the connection string, the stored procedure name and the ActiveTabIndex
public static void DataAccess(string connectionString,string spName, int activeTabIndex)
{
using (SqlConnection con = new SqlConnection(connectionString))
{
using (SqlCommand cmd = new SqlCommand(spName, con))
{
con.Open();
cmd.CommandType = CommandType.Text;
SqlDataReader rdr = cmd.ExecuteReader();
GridView gv = new GridView();
gv.DataSource = rdr;
gv.DataBind();
}
}
}
UDPATE: Okay, in the meantime I came up with
public partial class _Default : System.Web.UI.Page
{
string cs = ConfigurationManager.ConnectionStrings["dbcs"].ConnectionString;
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnMakeGridView_Click(object sender, EventArgs e)
{
TabContainer1.Tabs[TabContainer1.ActiveTabIndex].Controls.Add(GetData(cs, "spTest", TabContainer1.ActiveTabIndex));
}
public static GridView GetData(string connectionString,string spName, int activeIndex)
{
using (SqlConnection con = new SqlConnection(connectionString))
{
using (SqlCommand cmd = new SqlCommand(spName, con))
{
con.Open();
cmd.CommandType = CommandType.StoredProcedure;
SqlDataReader rdr = cmd.ExecuteReader();
GridView gv = new GridView();
gv.ID = "gv" + activeIndex.ToString();
gv.DataSource = rdr;
gv.DataBind();
return gv;
}
}
}
}

Update button keeps updating on click of Refresh in IE

I have a form wherein I populate content using stored procedure and I perform update actions on the content. Now my update button works fine. My problem is that each time I click on 'refresh' button in IE, the content gets updated and I don't want that to happen. I am new to .Net and all this ViewState stuff. Any help is appreciated..
Here is my code:
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
public void BindGridView()
{
string constring = ConfigurationManager
.ConnectionStrings["shaConnectionString"].ConnectionString;
using (SqlConnection con = new SqlConnection(constring))
{
using (SqlCommand cmd = new SqlCommand("spd_pc", con))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection = con;
cmd.Parameters.Add("#city", SqlDbType.VarChar).Value = txt_city.Text;
con.Open();
IDataReader idr = cmd.ExecuteReader();
GridView1.DataSource = idr;
GridView1.DataBind();
idr.Close();
con.Close();
}
}
}
protected void Button1_click(object sender, EventArgs e)
{
BindGridView();
}
private void DeleteRecords(int id)
{
string constring = ConfigurationManager.
ConnectionStrings["shaConnectionString"].ConnectionString;
using (SqlConnection conn = new SqlConnection(constring))
{
using (SqlCommand cmd = new SqlCommand("del_pc", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection = conn;
conn.Open();
cmd.Parameters.Add("#id", SqlDbType.VarChar).Value = id;
cmd.ExecuteNonQuery();
conn.Close();
}
}
}
protected void ButtonDelete_Click(object sender, EventArgs e)
{
foreach (GridViewRow row in GridView1.Rows)
CheckBox chkb = (CheckBox)row.FindControl("CheckBox1");
if (chkb.Checked)
{
int id = Convert.ToInt32(GridView1.DataKeys[row.RowIndex].Values[0]);
if (!(id.Equals(System.DBNull.Value)))
{
DeleteRecords(id);
}
}
}
BindGridView();
}
protected void Button2_Click(object sender, EventArgs e)
{
if (!IsCallback)
{
string active = "active";
string inactive = "inactive";
foreach (GridViewRow row in GridView1.Rows)
{
CheckBox chkb = (CheckBox)row.FindControl("CheckBox1");
if (chkb.Checked)
{
int id = Convert.ToInt32(GridView1.DataKeys[row.RowIndex].Values[0]);
string status = row.Cells[5].Text;
if (!(id.Equals(System.DBNull.Value)))
{
if ((String.Equals(active, status)))
UpdateRecords(id);
if ((String.Equals(inactive, status)))
UpdateRecords(id);
}
}
}
}
}
private void UpdateRecords(int id)
{
string constring = ConfigurationManager.
ConnectionStrings["shaConnectionString"].ConnectionString;
using (SqlConnection conn = new SqlConnection(constring))
{
using (SqlCommand cmd = new SqlCommand("upd_pc", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection = conn;
conn.Open();
cmd.Parameters.Add("#id", SqlDbType.VarChar).Value = id;
cmd.ExecuteNonQuery();
conn.Close();
}
}
BindGridView();
}
}
yes, this will happen. the problem is you are refreshing the post event of the button click. the solution is to redirect back to page after the update is complete.
button_click(...)
{
//save to db
Response.Redirect(Request.Referrer);
}
or something like that.
Now if the user clicks refresh it will submit the GET request to load the page, rather the POST to issue the button click event.
If you search for Post Get Redirect (or something like that) you will find lots of articles on the topic. describing both the situation you encountered and why this solution works.

Categories

Resources