How to add text to asp:BoundField in GridView? - asp.net

I have the following GridView in which data is being fed from the OleDB Database.
<asp:GridView ID="GridViewSavingsTracker" AutoGenerateColumns="false" runat="server">
<Columns>
...
<asp:BoundField DataField="interestRate" HeaderText="Interest Rate" />
...
</Columns>
</asp:GridView>
And I am reading the contents from the Database and printing in the GridView in the following manner:
protected void ShowGridView()
{
string connectionString = GetConnString();
OleDbConnection con = new OleDbConnection(connectionString);
con.Open();
string sqlQuery = "select * from ... ";
OleDbCommand showGridViewCommand = new OleDbCommand(showGridViewQuery, con);
showGridViewCommand.ExecuteNonQuery();
DataTable dt = new DataTable();
OleDbDataAdapter olda = new OleDbDataAdapter(showGridViewCommand);
olda.Fill(dt);
GridViewSavingsTracker.DataSource = dt;
GridViewSavingsTracker.DataBind();
con.Close();
}
What I want to do: I want to append % symbol to the contents of interestRate column in the GridView such that they should be displayed as 3% instead of 3. But the % symbol should not be inserted into the Database. In other words, the % symbol should only be used for display purposes in the GridView.

Depending on how you store the interest rate in the database will depend on which one of the below solutions remedy your question,
If the interest rates are formatted such that 0 = 0% and 1 = 100% you can use:
<asp:BoundField DataField="interestRate" HeaderText="Interest Rate" DataFormatString="{0:p}"/>
Documentation
Otherwise you will need to do a template
<columns>
<asp:TemplateField HeaderText="Interest Rate:">
<ItemTemplate>
<asp:Literal ID="IntRate" runat="server" Text='<%# Eval("InterestRate") + "%" %>'></asp:Literal>
</ItemTemplate>
</asp:TemplateField>
</columns>
Updating answer as per comments below
protected void GridViewSavingsTracker_RowCommand(object sender, GridViewCommandEventArgs e)
{
int index = Convert.ToInt32(e.CommandArgument);
var row = GridViewSavingsTracker.Rows[index];
var interestRate = ((Literal row.FindControl("IntRate")).Text;
if (e.CommandName == "SomeCommand")
{
TextBoxInterestRate.Text = interestRate;
}
}

Related

How to update database in SQL Server when I have checkbox in gridview?

I tried to make a message board.
After someone leave message, manager can check message context can be show for others or not.
I use gridView to connect to my SQL Server data, and there is a checkbox in the gridview.
If I checked checkbox, and click "sent" button, SQL Server data will be updated.
If I would like to update checkbox result into SQL Server data, what should I do?
This is my aspx
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="id" OnRowDeleting="GridView1_RowDeleting">
<Columns>
<asp:TemplateField HeaderText="check or not" SortExpression="replyCheck">
<EditItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" Checked='<%# Bind("replyCheck") %>' />
</EditItemTemplate>
<ItemTemplate>
<asp:CheckBox ID="CheckBox2" runat="server" Checked='<%# Bind("replyCheck") %>' Enabled="True" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<br/>
<asp:Button ID="Button1" runat="server" Text="sent" OnClick="Button1_Click"/>
And this is my aspx.cs - if I use foreach, it can't update into my database
protected void Button1_Click(object sender, EventArgs e)
{
var id = GridView1.DataKeys.ToString();
foreach (GridViewRow row in GridView1.Rows)
{
CheckBox reply = (row.Cells[0].FindControl("CheckBox2") as CheckBox);
if (reply.Checked)
{
SqlConnection sqlConnection = new SqlConnection(getsql);
sqlConnection.Open();
SqlCommand cmd = new SqlCommand($"UPDATE reply SET replyCheck ='1' WHERE (id = {id})", sqlConnection);
cmd.ExecuteNonQuery();
sqlConnection.Close ();
DataBind();
}
}
}
If I use for, it showed error about "datakey array"
protected void Button1_Click(object sender, EventArgs e)
{
var id = GridView1.DataKeys.ToString();
int messageCheck, displayCheck;
SqlConnection sqlConnection = new SqlConnection(getsql);
sqlConnection.Open();
for (int i = 0; i < GridView1.Rows.Count; i++)
{
CheckBox message = (CheckBox)GridView1.Rows[i].FindControl("CheckBox2");
if (message.Checked == true)
{
messageCheck = 1;
SqlCommand cmd1 = new SqlCommand($"UPDATE reply SET replyCheck = {messageCheck} WHERE (id = {id})", sqlConnection);
cmd1.ExecuteNonQuery();
}
else
{
messageCheck = 0;
SqlCommand cmd2 = new SqlCommand($"UPDATE reply SET replyCheck = {messageCheck} WHERE (id = {id})", sqlConnection);
cmd2.ExecuteNonQuery();
}
}
sqlConnection.Close();
}
Without javascript, how could I do it?
Thanks for you all
Ok, the way this works is that datafields (non templated columns) in the GV use the cells[] collection.
However, for templated columns, we have to use find control.
And also we will use the data keys feature, as that lets us have/use/work with the database PK row ID, but NOT have to display in the markup/grid for users.
Ok, so here is a GV with both datafiles (the cells()), and also check box.
We will select the check boxes, and then with a save button, send changes back to database.
So, our markup:
<div style="width:50%;padding:25px">
<asp:GridView ID="GVHotels" runat="server" class="table borderhide"
AutoGenerateColumns="false" DataKeyNames="ID">
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" />
<asp:BoundField DataField="City" HeaderText="City" />
<asp:BoundField DataField="HotelName" HeaderText="HotelName" HeaderStyle-Width="200" />
<asp:BoundField DataField="Description" HeaderText="Description" />
<asp:TemplateField HeaderText="Smoking" ItemStyle-HorizontalAlign="Center" >
<ItemTemplate>
<asp:CheckBox ID="chkSmoking" runat="server"
Checked='<%# Eval("Smoking") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Balcony" ItemStyle-HorizontalAlign="Center" >
<ItemTemplate>
<asp:CheckBox ID="chkBalcony" runat="server"
Checked='<%# Eval("Balcony") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Button ID="cmdSave" runat="server" Text="Save changes" CssClass="btn"/>
</div>
And now our code to fill out above could be say this:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadGrid();
}
void LoadGrid()
{
using (SqlConnection con = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (SqlCommand cmdSQL =
new SqlCommand("SELECT * from tblHotels ORDER BY HotelName ", con))
{
con.Open();
GVHotels.DataSource = cmdSQL.ExecuteReader();
GVHotels.DataBind();
}
}
}
And now we see this:
Now, there is two ways we can update the database. We could in fact update using a datatable, and in one whole shot upate the datbase.
but, we just loop the GV, and execute updates. (if I have time, I'll try and post the 2nd more cool approach).
So, our button to update/save changes (for check boxes). Could be this:
protected void cmdSave_Click(object sender, EventArgs e)
{
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
conn.Open();
string strSQL = "UPDATE tblHotels Set Smoking = #S, Balcony = #B " +
"WHERE ID = #ID";
foreach (GridViewRow gRow in GVHotels.Rows)
{
CheckBox cSmoke = (CheckBox)gRow.FindControl("chkSmoking");
CheckBox cBlacony = (CheckBox)gRow.FindControl("chkBalcony");
int PKID = (int)GVHotels.DataKeys[gRow.RowIndex]["ID"];
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
{
cmdSQL.Parameters.Add("#S", SqlDbType.Bit).Value = cSmoke.Checked;
cmdSQL.Parameters.Add("#B", SqlDbType.Bit).Value = cBlacony.Checked;
cmdSQL.Parameters.Add("#ID", SqlDbType.Int).Value = PKID;
cmdSQL.ExecuteNonQuery();
}
}
}
}
Note how we use row index to get the PK row ID. NOTE the DataKeys setting for the GV. This allows you to use/have/enjoy use of the database PK row ID (named "ID" in this code example), and NOT have to display/include the PK in the GV display.
Note that you would continue to use cells() collection for NON templated columns. But for any templated column - you have to use FindControl on that row, pluck out the control, and then you can have at it in regards to that control value.
We could also pull each GV row into a data table, and execute ONE datatable update into the database. But, as the above code shows - we actually keep the connection open for the update - and thus not a big deal either way.
Kindly check with this code
Protected Sub Button1_Click(sender As Object, e As EventArgs)
For Each row In GridView1.Rows
Dim chk As CheckBox = row.FindControl("CheckBox2")
If chk.Checked Then
'sql update query
Else
End If
Next
End Sub

how to change the gridview row value after button click event

I have a table in four columns see screenshot here:
But I need two columns in that table name and gender see screenshot here:
Display in this type but I have required after click the button row value will change in GridView button out side in GridView e.g. row value 1,2 can instead male and female that is my requirement.
You need to fetch that data from database in dataset or datatable and assign that as DataSource to the GridView and call DataBind on that GridView. Now in RowDataBound event compare the value and assign value to UI label / literal based on that.
Below is GridView in aspx page.
<asp:GridView runat="server" AutoGenerateColumns="false" ID="GridView1" OnRowDataBound="GridView1_RowDataBound">
<Columns>
<asp:TemplateField HeaderText="Employee Name">
<ItemTemplate>
<asp:Literal ID="ltrlEmpName" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Employee Gender">
<ItemTemplate>
<asp:Literal ID="ltrlEmpGender" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
In code behind, lets say you want to assign the datasource to this GridView in page load or any other method. Below will be its code. Note that in sample here I have taken dummy DataTable and filled values for simplicity, you need to fill that DataTable from db values.
protected void Page_Load(object sender, EventArgs e)
{
// Dummy data table below, that needs to be replaced by datatable / dataset fetched from database.
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("EmpName", typeof(string)));
dt.Columns.Add(new DataColumn("EmpGender", typeof(int)));
DataRow dr1 = dt.NewRow();
dr1["EmpName"] = "Romesh";
dr1["EmpGender"] = 1;
dt.Rows.Add(dr1);
DataRow dr2 = dt.NewRow();
dr2["EmpName"] = "Sandya";
dr2["EmpGender"] = 2;
dt.Rows.Add(dr2);
// Bind the datasource to gridview.
GridView1.DataSource = dt;
GridView1.DataBind();
}
protected void GridView1_RowDataBound(object sender, System.Web.UI.WebControls.GridViewRowEventArgs e)
{
if (e.Row.RowType == System.Web.UI.WebControls.DataControlRowType.DataRow)
{
System.Web.UI.WebControls.Literal ltrlEmpName = (System.Web.UI.WebControls.Literal)e.Row.FindControl("ltrlEmpName");
System.Web.UI.WebControls.Literal ltrlEmpGender = (System.Web.UI.WebControls.Literal)e.Row.FindControl("ltrlEmpGender");
// Bind employee name to its label.
ltrlEmpName.Text = Convert.ToString(DataBinder.Eval(e.Row.DataItem, "EmpName"));
// Bind employee gender to its label based on its value.
if (Convert.ToString(DataBinder.Eval(e.Row.DataItem, "EmpGender")) == "1")
{
ltrlEmpGender.Text = "Male";
}
else if (Convert.ToString(DataBinder.Eval(e.Row.DataItem, "EmpGender")) == "2")
{
ltrlEmpGender.Text = "Female";
}
else
{
ltrlEmpGender.Text = "Other";
}
}
}
You will get out as Table as below.

Putting data from SQL query into grid view asp.net

I have a grid box in which I want to fill data from a database where the username is one and their location was added in the last 24 hours.
I have tested the SQL query and it is working fine, however when trying to put the data in a grid box nothing happens.
Here is the code I have used in the aspx.cs file:
public partial class last24hours : System.Web.UI.Page
{
SqlConnection con = new SqlConnection(#"Data Source = sql2008.net.dcs.hull.ac.uk; Initial Catalog = rde_514872; Integrated Security = True");
protected void Page_Load(object sender, EventArgs e)
{
using (SqlCommand cmd = new SqlCommand())
{
cmd.CommandText = "SELECT Location FROM StaffLocation WHERE [Date and Time]>= getdate()-1 AND [Username] = '1'";
cmd.Connection = con;
DataTable dt = new DataTable();
using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
{
sda.Fill(dt);
GridView1.DataSource = dt;
GridView1.DataBind();
}
}
}
}
gridView1 is an empty grid view I have made with no sql source.
This is how the gridview is initialised in the aspx file:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False">
</asp:GridView>
You have AutoGenerateColumns set to false. And since you haven't defined any columns manually, of course nothing is going to show up. There's two fixes:
Set auto generate columns to true.
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="true" />
Or manually define your columns
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false">
<Columns>
<asp:BoundField DataField="Location" HeaderText="Location" SortExpression="Location" />
</Columns>
</asp:GridView>

Stop Textbox in GridView Losing Data on Postback

I have a GridView which I dynamically add rows to through the button_OnClick event, this adds a new row with the Product name & Product ID from a DropDownList and also contains a column with an empty text box for user input.
My problem is that when I test it and enter data in the text box, then add another Product, the post back causes my data to be lost (the correct number of rows are still there with product names / ids).
<asp:GridView runat="server" ID="grdSelectedProducts" BorderWidth="1px" CellPadding="3" CellSpacing="2" AutoGenerateColumns="False" OnRowDataBound="grdSelectedProducts_OnRowDataBound" ShowHeaderWhenEmpty="True" DataKeyNames="ProductId"
OnRowCommand="grdSelectedProducts_RowCommand" OnRowDeleted="grdSelectedProducts_RowDeleted" OnRowDeleting="grdSelectedProducts_RowDeleting" EmptyDataText="Please select a Product and click 'Add'" EnableViewState="True">
<Columns>
<asp:BoundField DataField="Product" HeaderText="Product" ReadOnly="False"/>
<asp:TemplateField HeaderText="Description">
<ItemTemplate>
<asp:TextBox runat="server" ID="txtDescriptionEntry" Text="" style="width:98% !important" EnableViewState="True"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton runat="server" ID="linkDelete" runat="server" CommandName="Delete" CommandArgument="<%# Container.DataItemIndex %>">Remove</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="ProductId" HeaderText="ProductId" ReadOnly="False" Visible="False" />
</Columns>
</asp:GridView>
How can I avoid postback scrapping the data on each txtDescriptionEntry that is created? There could be between 0 and an infinite number of these text boxes, so I won't have exact names at any one time.
Edit, as per a comment below I'm including the code for how I add rows to the grid:
private DataTable ProductDataTable
{
get {return ViewState["ProductDataTable"] as DataTable ?? new DataTable(); }
set { ViewState["ProductDataTable"] = value; }
}
private DataTable CreateDataTable(bool isAddingValue, string selectedProduct, string selectedId)
{
// if isAddingValue is FALSE then it isn't from a button click to add a Product, it is just
// a call to create the datatable
DataTable dataTable = ProductDataTable;
if (!dataTable.Columns.Contains("Product"))
{
dataTable.Columns.Add("Product");
dataTable.Columns.Add("Description"); // This column is free format text that the user enters.
dataTable.Columns.Add("ProductId");
}
if (isAddingValue)
{
// Get the data from ViewState
//dataTable = ProductDataTable;
DataRow dataRow;
dataRow = dataTable.NewRow();
dataRow["Product"] = selectedProduct;
dataRow["ProductId"] = selectedId;
dataTable.Rows.Add(dataRow);
}
else
{
grdSelectedProducts.DataSource = null;
grdSelectedProducts.DataSource = ProductDataTable;
grdSelectedProducts.DataBind();
}
// Save the data back to ViewState
ProductDataTable = dataTable;
return dataTable;
}
protected void btnAddProduct_OnClick(object sender, EventArgs e)
{
string selectedProduct = ddlProduct.SelectedItem.Text;
string selectedId = ddlProduct.SelectedValue;
DataTable dataTable = CreateDataTable(true, selectedProduct, selectedId);
grdSelectedProducts.DataSource = dataTable;
grdSelectedProducts.DataBind();
}
protected void grdSelectedProducts_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Delete")
{
if (!string.IsNullOrEmpty(e.CommandArgument.ToString()))
{
int rowIndex = Convert.ToInt32(e.CommandArgument);
DataTable table = CreateDataTable(false, string.Empty, string.Empty);
table.Rows.RemoveAt(rowIndex);
grdSelectedProducts.DataSource = table;
grdSelectedProducts.DataBind();
}
}
}
And in the Page_Load event, if it isn't a PostBack there is also binding of an empty list
grdSelectedProducts.DataSource = new List<Products>();
grdSelectedProducts.DataBind();
I figured this out, not the nicest solution (so I probably wouldn't recommend it) but it got me out of a jam.
I used the OnRowDataBound event so for each row that was being bound to the table I would use the RowIndex to get the appropriate row in the DataTable, I would then assign the text box (also obtained via the index) the value from the DT. Example below.
protected void grdSelectedproducts_OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowIndex > -1)
{
TextBox txtDescription = e.Row.FindControl("txtDescriptionEntry") as TextBox;
if (txtDescription != null)
{
DataTable dt = ProductDataTable;
DataRow row = dt.Rows[e.Row.RowIndex] as DataRow;
txtDescription.Text = row[1].ToString();
}
}
}

I need to use Checkboxlist within a GridView which binds data from other table

I have to fill checkboxlist which is within the gridview control.
<asp:GridView ID="gvProject" CssClass="Gridview viewproject-th-col-remov" runat="server" AutoGenerateColumns="false" OnRowDataBound="gvProject_RowDataBound" DataKeyNames="ProjectID" AllowPaging="True">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="lnkContract" runat="server" Text="Contract" ControlStyle-CssClass="pdf-download-link"OnClick="DownloadFile" CommandArgument='<%# Eval("ProjectId") %>'></asp:LinkButton>
<asp:CheckBoxList ID="chkAdSpace" runat="server"></asp:CheckBoxList>
</ItemTemplate>
</asp:TemplateField>
</Columns> </asp:GridView>
Then I have bound the data in checkboxlist like this.
private void BindList(Int32 _id)
{
DataTable dtAdSpace = new DataTable();
dtAdSpace = CommonDataViews.GetAdSpaceSearch(_id);
if (dtAdSpace.Rows.Count > 0)
{
chkAdSpace.DataSource = dtAdSpace;
chkAdSpace.DataTextField = "adspace";
chkAdSpace.DataValueField = "adspace";
chkAdSpace.DataBind();
}
}
But, problem is chkASpace does not accessible int BindList(Int32 _id) or throught the form. Please help me why this is not accessible like LinkButton which I used.
Thanks in advance.
Raja
Retrieve the data to bind in a DataTable.
In GridView_RowDataBound event, Bind the Checkboxlist with the DataTable. Get the Checkboxlist by using FindControl. Like below:
protected void gvProject_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
CheckBoxList cblProject = (CheckBoxList)e.Row.FindControl("chkAdSpace");
cblProject.DataSource = dtAdSpace;
cblProject.DataTextField = "adspace";
cblProject.DataValueField = "adspace";
cblProject.DataBind();
}
}
I think the question was how to do it within ASP.net and not from code behind.
ie: Gridview binds to a datasource, but within the gridview there is a column with a checkboxlist and its own datasource. Using Eval("yourcolumn") tries to bind to the main datasource of the GridView and not the checkboxlist.
Sorry I do not have the answer, as I am trying to determine that as well.
To Check All the ckeckboxes in the list simply iterate through each checkbox to check them.After Databind.
foreach (ListItem listItem in chkAdSpace.Items)
{
listItem.Selected = true;
}
Here is my answer:
The GridView code is:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="id" DataSourceID="SqlDataSource1"
OnRowDataBound="GridView1_RowDataBound">
<Columns>
<asp:BoundField DataField="id" HeaderText="id" InsertVisible="False" ReadOnly="True" SortExpression="id" />
<asp:BoundField DataField="name" HeaderText="name" SortExpression="name" />
<asp:TemplateField HeaderText="Subjects">
<ItemTemplate>
<asp:CheckBoxList ID="CheckBoxList1" runat="server" DataTextField="fprefid" DataValueField="fprefid">
</asp:CheckBoxList>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Here is the C# code:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
CheckBoxList cbl = (CheckBoxList)e.Row.FindControl("CheckBoxList1");
object objTemp = GridView1.DataKeys[e.Row.RowIndex].Value as object;
string id = objTemp.ToString();
SqlConnection con1 = new SqlConnection(constr);
SqlConnection con2 = new SqlConnection(constr);
SqlCommand com1 = new SqlCommand("select prefid from preferences",con1);
if (con1.State == ConnectionState.Closed)
con1.Open();
if (con2.State == ConnectionState.Closed)
con2.Open();
SqlDataReader dreader1 = com1.ExecuteReader();
if(dreader1.HasRows)
{
while(dreader1.Read())
{
SqlCommand com2 = new SqlCommand("select fprefid from person_pref where fpersonid='" + id + "' and fprefid = '" + dreader1["prefid"] + "'", con2);
SqlDataReader dreader2 = com2.ExecuteReader();
ListItem li = new ListItem();
if (dreader2.HasRows)
{
li.Text = dreader1["prefid"].ToString();
li.Selected = true;
}
else
{
li.Text = dreader1["prefid"].ToString();
li.Selected = false;
}
cbl.Items.Add(li);
dreader2.Close();
}
}
}
}

Resources