I have a gridview with textbox inside
I want to get value of this textbox on button click
But I always receiving "0" (default) value
I think this problem related to viewstate but I'm not sure
Tell me please what I'm doing wrong?
Source code:
protected void Page_Load(object sender, EventArgs e)
{
DataSet dataSet = new DataSet("MyDataSet");
DataTable table = new DataTable();
table.Columns.Add(new DataColumn("NameValue"));
table.Columns.Add(new DataColumn("Number"));
table.Columns.Add(new DataColumn("NumberValue"));
dataSet.Tables.Add(table);
DataRow row = dataSet.Tables[0].NewRow();
row[0] = "Name";
row[1] = "0";
dataSet.Tables[0].Rows.Add(row);
this.MyGridView.DataSource = dataSet;
this.MyGridView.DataBind();
}
protected void Button1_Click(object sender, EventArgs e)
{
TextBox txtsn = ((TextBox)this.MyGridView.Rows[0].FindControl("NumberTextBox"));
string sn = txtsn.Text;
}
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
<asp:GridView ID="MyGridView" AutoGenerateColumns="false" ShowHeader="false" runat="server" >
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="NameLabel" runat="server" Text='<%#Eval("NameValue")%>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:TextBox ID="NumberTextBox" runat="server" Text='<%#Eval("NumberValue")%>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
</form>
</body>
The problem is that you always bind the grid to it's DataSource even on postbacks. That overrides all changes made by the user.
Instead use the IsPostBack property:
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostback)
{
DataSet dataSet = new DataSet("MyDataSet");
DataTable table = new DataTable();
table.Columns.Add(new DataColumn("NameValue"));
table.Columns.Add(new DataColumn("Number"));
table.Columns.Add(new DataColumn("NumberValue"));
dataSet.Tables.Add(table);
DataRow row = dataSet.Tables[0].NewRow();
row[0] = "Name";
row[1] = "0";
dataSet.Tables[0].Rows.Add(row);
this.MyGridView.DataSource = dataSet;
this.MyGridView.DataBind();
}
}
You need to reload the DataSource only if something was changed(f.e. a record was deleted or added, the user clicked a sort-column or you have paging). But then you should do that only in the appropriate event handlers and not in page_load. So it's best to wrap this code in a method which you can call from anywhere.
You're data binding your grid on postbacks, which is causing this issue. You want to check to see if the request is a post:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostback)
{
DataSet dataSet = new DataSet("MyDataSet");
DataTable table = new DataTable();
table.Columns.Add(new DataColumn("NameValue"));
table.Columns.Add(new DataColumn("Number"));
table.Columns.Add(new DataColumn("NumberValue"));
dataSet.Tables.Add(table);
DataRow row = dataSet.Tables[0].NewRow();
row[0] = "Name";
row[1] = "0";
dataSet.Tables[0].Rows.Add(row);
this.MyGridView.DataSource = dataSet;
this.MyGridView.DataBind();
}
}
Related
I can't solve one thing, I want to paint some rows of the GridView depending on a column. I have no problems with this, but when I change the page, I can't get it to paint.
This is how I do the pagination
GridView2.PageIndex = e.NewPageIndex;
loadgrid();
paintpagin(e.NewPageIndex);
So I try to paint it
GridView2.PageIndex = newPageIndex;
foreach (GridViewRow Rowe in GridView2.Rows)
{
CheckBox Rc = (CheckBox)Rowe.FindControl("rdaprobar");
RadioButton Ri = (RadioButton)Rowe.FindControl("rdpendiente");
RadioButton Rd = (RadioButton)Rowe.FindControl("rdCandelar");
if (Rc.Checked == true)
{
GridView2.Rows[Rowe.DataItemIndex].BackColor = ColorTranslator.FromHtml("#bcf5be");
}
}
The even to use for highlights, formatting, etc.?
use the Grid row data bound event.
So, first up, our markup:
<asp:GridView ID="GHotels" runat="server" CssClass="table" AutoGenerateColumns="false"
width="45%" DataKeyNames="ID" OnRowDataBound="GHotels_RowDataBound" AllowPaging="True"
OnPageIndexChanging="GHotels_PageIndexChanging" >
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" />
<asp:TemplateField HeaderText="HotelName">
<ItemTemplate>
<asp:Label ID="txtHotel" runat="server" Text='<%# Eval("HotelName") %>' ></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Description" HeaderText="Description" ItemStyle-Width="270" />
</Columns>
<PagerStyle CssClass="GridPager" />
</asp:GridView>
Code to load:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadData();
}
void LoadData()
{
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
string strSQL =
"SELECT * FROM tblHotels WHERE Description is not null ORDER BY HotelName";
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
{
DataTable rstData = new DataTable();
conn.Open();
rstData.Load(cmdSQL.ExecuteReader());
GHotels.DataSource = rstData;
GHotels.DataBind();
}
}
}
Our pager code (and NOTE YOU HAVE the load of the grid before the pager - chec your code!!!).
protected void GHotels_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GHotels.PageIndex = e.NewPageIndex;
LoadData();
}
Ok, we now have this:
Now, I highlight each hotel if it is active. NOTE very careful, I don't have that column "active" in the GV, but it was/is part of the data source. So, for bonus points, I demonstrate how to get/grab/use columns that you don't render or have in the GV, but in fact is part of the data source.
So, our code to highlight, we have this:
protected void GHotels_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// get binding data source
DataRowView gData = e.Row.DataItem as DataRowView;
if ((bool)gData["Active"]) {
// Label tHotel = e.Row.FindControl("txtHotel") as Label;
// tHotel.BackColor = System.Drawing.Color.LightSteelBlue;
e.Row.Cells[2].BackColor = System.Drawing.Color.LightSteelBlue;
}
}
}
So, we now have this:
So do NOT try and loop each row of the GV - use the row data bound to highlight and format as per above.
If i want to populate a DropdownList in a GridView what will be the best way? use GridView 'OnRowDataBound' event and fetch query everytime to db or get all data first and put it on datatable and do further work from this datatable ?
As your question is unclear about your requirement, I assume that you want to bind dropdownlist inside the Gridview using OnRowDataBound event of gridview.
So here are the steps:-
Add a Gridview HTML in your aspx page with DropDownList in ItemTemplate of TemplateField.
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" OnRowDataBound="OnRowDataBound">
<Columns>
<asp:BoundField HeaderText="Name" DataField="ContactName" />
<asp:TemplateField HeaderText = "Country">
<ItemTemplate>
<asp:Label ID="lblCountry" runat="server" Text='<%# Eval("Country") %>' Visible = "false" />
<asp:DropDownList ID="ddlCountries" runat="server">
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Then you need to bind the gridview with records which will come from the database.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
GridView1.DataSource = GetData("SELECT ContactName, Country FROM Customers");
GridView1.DataBind();
}
}
private DataSet GetData(string query)
{
string conString = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
SqlCommand cmd = new SqlCommand(query);
using (SqlConnection con = new SqlConnection(conString))
{
using (SqlDataAdapter sda = new SqlDataAdapter())
{
cmd.Connection = con;
sda.SelectCommand = cmd;
using (DataSet ds = new DataSet())
{
sda.Fill(ds);
return ds;
}
}
}
}
Then the code for OnRowDataBound will follow like below :-
protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
//Find the DropDownList in the Row
DropDownList ddlCountries = (e.Row.FindControl("ddlCountries") as DropDownList);
ddlCountries.DataSource = GetData("SELECT DISTINCT Country FROM Customers");
ddlCountries.DataTextField = "Country";
ddlCountries.DataValueField = "Country";
ddlCountries.DataBind();
//Add Default Item in the DropDownList
ddlCountries.Items.Insert(0, new ListItem("Please select"));
//Select the Country of Customer in DropDownList
string country = (e.Row.FindControl("lblCountry") as Label).Text;
ddlCountries.Items.FindByValue(country).Selected = true;
}
}
See the Reference link for your reference
Also see the Working demo for your reference
Hope that helps.
I have GridView, which is not auto generating columns. In GridView there are 3 columns: one for Checkbox(to delete selected row from DataTable),
one for edit link button(to edit current row),
and the third one is for showing data from DataTable.
I am binding it from DataTable.
I have a primary key in DataTable.
Now my problem is when I am clicking on edit link button I am not getting primary key(id) from
datatable for selected row in grid view (i think row is not selected when i am clicking on edit link button). I cant take row index to match it with datatable primary key as data bound in GridView is filtered.
What I have tried is, I created one more column in grid view as hidden which is primary key column from DataTable. But for that too I am not getting data in hidden column of row which is clicked for edit.
Someone please help with a new idea, or solution for what i am trying.. thanx in advance.
Plese try as follow.. for update, selected ID can be got in gv_RowCommand event. For delection [multiple select checbox] check in btnDelete_Click, enter code here
--------------aspx code--------------------------------
<asp:Button ID="btnDelete" runat="server" Text="Delete"
onclick="btnDelete_Click" />
<asp:GridView ID="gv" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID" onrowcommand="gv_RowCommand"
onrowupdating="gv_RowUpdating">
<Columns>
<asp:TemplateField HeaderText="Delete">
<ItemTemplate>
<asp:CheckBox ID="chkSel" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Update">
<ItemTemplate>
<asp:LinkButton runat="server" CommandArgument='<%# Eval("ID") %>' CommandName="Update" text="Update" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="NAME" HeaderText="Name" />
</Columns>
</asp:GridView>
---------------code behind---------------------------
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
BindData();
}
private void BindData()
{
DataTable dt = new DataTable();
dt.Columns.Add("ID");
dt.Columns.Add("NAME");
DataRow dr = dt.NewRow();
dr[0] = "1";
dr[1] = "James";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr[0] = "2";
dr[1] = "Paul";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr[0] = "3";
dr[1] = "Mary";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr[0] = "4";
dr[1] = "Susan";
dt.Rows.Add(dr);
gv.DataSource = dt;
gv.DataBind();
}
protected void gv_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Update")
{
string id = e.CommandArgument.ToString();
}
}
protected void gv_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
}
protected void btnDelete_Click(object sender, EventArgs e)
{
string idList = "";
for (int i = 0; i < gv.Rows.Count; i++)
{
CheckBox chk = (CheckBox)gv.Rows[i].FindControl("chkSel");
if (chk != null && chk.Checked)
idList += gv.DataKeys[i].Value.ToString() + ",";
}
}
I have a gridview in which every row contains a dropdownlist. I want to bind every dropdownlist dynamically. Can someone tell me how can i do it. Thanks in Advance
If you are using template column then you can bind your drop-down from mark-up using data-binding expressions. For example,
<asp:TemplateField HeaderText="XYZ">
<ItemTemplate>
<asp:DropDownList runat="server" ID="MyDD" DataSourceId="MyDataSource" />
</ItemTemplate>
</asp:TemplateField>
Above is assuming that your drop-down data in constant across rows. If it is changing then you can use data-binding expression such as
<asp:DropDownList runat="server" DataSource='<%# GetDropDownData(Container) %>' DataTextField="Text" DataValueField="Value" />
GetDropDownData will be a protected method in code-behind that will return the data (data-table, list, array) for the given row.
You can use GridView.RowDataBound event (or RowCreated event) in code-behind to fill drop-downs. For example,
protected void GridView_RowDataBound(Object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
// Find the drop-down (say in 3rd column)
var dd = e.Row.Cells[2].Controls[0] as DropDownList;
if (null != dd) {
// bind it
}
/*
// In case of template fields, use FindControl
dd = e.Row.Cells[2].FindControl("MyDD") as DropDownList;
*/
}
}
In addition to the proposed methods, you may also bind your controls within your markup, in this way:
<asp:GridView ID="MyGrid" runat="server" DataSourceID="MyDataSource1">
<Columns>
<asp:TemplateField>
<EditItemTemplate>
<asp:DropDownList ID="DropDownList1" runat="server" SelectedValue='<%# Bind ("CustomerId") %>' DataSourceID="CustomersDataSource" DataTextField="CustomerName" DataValueField="CustomerId" >
</asp:DropDownList>
</EditItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Here is your gridview
<asp:GridView ID="grvExcelData" runat="server" onrowdatabound="GridView2_RowDataBound">
<HeaderStyle BackColor="#df5015" Font-Bold="true" ForeColor="White" />
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:DropDownList ID="DrdDatabase" Width="100px" runat="server">
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
and your RowDataBound event for the gridview would be
protected void GridView2_RowDataBound(object sender, GridViewRowEventArgs e)
{
string cities = "maxico,chennai,newdelhi,hongkong";
string [] arr = cities.Split(',');
// Instead of string array it could be your data retrieved from database.
if (e.Row.RowType == DataControlRowType.DataRow)
{
DropDownList ddl = (DropDownList)e.Row.FindControl("DrdDatabase");
foreach (string colName in arr )
ddl.Items.Add(new ListItem(colName));
}
}
protected void gvSalesAppData_RowDataBound(Object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DropDownList ddlCurrentPhase = (DropDownList)e.Row.FindControl("ddlCurrentPhase");
DropDownList ddlProductFamily = (DropDownList)e.Row.FindControl("ddlProductFamily");
DropDownList ddlProductGroup = (DropDownList)e.Row.FindControl("ddlProductGroup");
DropDownList ddlETProgramManager = (DropDownList)e.Row.FindControl("ddlETProgramManager");
DropDownList ddlPLMForTheProduct = (DropDownList)e.Row.FindControl("ddlPLMForTheProduct");
TrackingToolObj.BindCurrentPhases(ddlCurrentPhase);
TrackingToolObj.BindCurrentPhases(ddlProductFamily);
TrackingToolObj.BindProductGroups(ddlProductGroup);
TrackingToolObj.GetEmployeesBasedOnRoleTypeId(ddlETProgramManager, (int)OSAEnums.RoleTypes.ProgramManager, false);
TrackingToolObj.GetEmployeesBasedOnRoleTypeId(ddlPLMForTheProduct, (int)OSAEnums.RoleTypes.PLM, false);
}
}
Binding the GridView
Below is the code to Bind the GridView control with data.
C#
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
this.BindData();
}
}
private void BindData()
{
string query = "SELECT top 10 * FROM Customers";
SqlCommand cmd = new SqlCommand(query);
gvCustomers.DataSource = GetData(cmd);
gvCustomers.DataBind();
}
private DataTable GetData(SqlCommand cmd)
{
string strConnString = ConfigurationManager.ConnectionStrings["conString"].ConnectionString;
using (SqlConnection con = new SqlConnection(strConnString))
{
using (SqlDataAdapter sda = new SqlDataAdapter())
{
cmd.Connection = con;
sda.SelectCommand = cmd;
using (DataTable dt = new DataTable())
{
sda.Fill(dt);
return dt;
}
}
}
}
as the title says, How do I disable the select button text in a gridview after clicking it once? I want to click it once, then have the select cell area render an image (and the image not clickable or linking to anything).
Any ideas?
protected void Page_Load(object sender, EventArgs e)
{
dn = new holdDataContext();
if (!(Page.IsPostBack))
{
// GridView1.DataSource = dn.tennis.ToList();
// GridView1.DataBind();
GridView1.DataSource = from c in dn.tennis
orderby c.ID descending
select c;
GridView1.DataBind();
}
}
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
DataSet ds = null;
if (Session["oro"] == null)
{
ds = new DataSet();
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("Name"));
dt.Columns.Add(new DataColumn("Description"));
ds.Tables.Add(dt);
Session["oro"] = ds;
}
else
{
ds = (DataSet)Session["oro"];
}
DataRow row = ds.Tables[0].NewRow();
row["Name"] = GridView1.Rows[GridView1.SelectedIndex].Cells[2].Text;
row["Description"] = GridView1.Rows[GridView1.SelectedIndex].Cells[3].Text;
ds.Tables[0].Rows.Add(row);
}
you'll need a combination of aspx markup and code-behind:
aspx:
<asp:GridView ID="gvSample" runat="server"
DataKeyNames="CustomerID"
onselectedindexchanged="gvSample_SelectedIndexChanged">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="btnSelect" runat="server" CommandName="Select" Text="Select"></asp:LinkButton>
<asp:Image ID="imgSelect" runat="server" ImageUrl="~/imgs/whatever.jpg" Visible="false" />
</ItemTemplate>
code-behind:
protected void gvSample_SelectedIndexChanged(object sender, EventArgs e) {
LinkButton linkButton = gvSample.SelectedRow.Cells[0].FindControl("btnSelect") as LinkButton;
Image imgWhatever = gvSample.SelectedRow.Cells[0].FindControl("imgSelect") as Image;
linkButton.Enabled = false;
linkButton.Visible = false;
imgWhatever.Visible = true;
}
so, in the ItemTemplate markup of the GridView, specify the image you want to replace the Select button with but make it invisible, then disable the Select button in place of the image by swapping visibility between both objects within the event handler method gvSample_SelectedIndexChanged in the code-behind, which is what gets triggered upon clicking Select button. Since FindControl returns objects of type Control you'll have to cast to the LinkButton type of your Select button.