add textbox in DataTable aspx.net - c#

i want to add textBox into dataTable row.I dont know how to do that.Is it possible to add textBox to a dataTable?First it give me this error:
Index was out of range. Must be non-negative and less than the size of
the collection. Parameter name: index
Here is my code:
Markup:
<asp:GridView ID="GridView2" runat="server" ShowHeader="false" OnRowDataBound="GridView2_RowDataBound">
<Columns>
<ItemTemplate >
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Code Behind:
private void AddNewRecordRowToGrid()
{
DataTable dt = new DataTable();
DataRow dr;
dt.TableName = "table";
dt.Columns.Add(new DataColumn("Zabeleshka", typeof(TextBox)));
dr = dt.NewRow();
dt.Rows.Add(dr);
ViewState["marks"] = dt;
if (ViewState["marks"] != null)
{
DataTable dtCurrentTable = (DataTable)ViewState["marks"];
DataRow drCurrentRow = null;
if (dtCurrentTable.Rows.Count > 0)
{
for (int i = 1; i <= dtCurrentTable.Rows.Count; i++)
{
TextBox TextBox1 = (TextBox)GridView2.Rows[0].FindControl("TextBox1");
drCurrentRow["Zabeleshka"] = TextBox1.Text;
if (dtCurrentTable.Rows[0][0].ToString() == "")
{
dtCurrentTable.Rows[0].Delete();
dtCurrentTable.AcceptChanges();
}
dtCurrentTable.Rows.Add(drCurrentRow);
ViewState["marks"] = dtCurrentTable;
GridView2.DataSource = dtCurrentTable;
GridView2.DataBind();
}
}
}
}

You can add a textbox into a gridview no problem then find it from the code behind in the RowDataBound Grid Method. Your problem is more than likely the fact that you have closed your TemplateField and have not opened one. You need to add
<asp:TemplateField>
above your
<ItemTemplate>.

As your markup code i think you want Text Box inside Gridview with containing some value into that,
for this,
first of all your markup is not correct, the correct one is,
<asp:GridView ID="GridView2" runat="server" ShowHeader="false" OnRowDataBound="GridView2_RowDataBound">
<Columns>
<asp:TemplateField> <%-- you have not opened it in your markup --%>
<ItemTemplate >
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
and in code behind,
to get the textbox value you need
TextBox TextBox1 = (TextBox)GridView2.Rows[0].FindControl("TextBox1");
edited,
in your code,
for (int i = 1; i <= dtCurrentTable.Rows.Count; i++)
{
TextBox TextBox1 = (TextBox)GridView2.Rows[0].FindControl("TextBox1");
drCurrentRow["Zabeleshka"] = TextBox1.Text;
the for loop condition is (i <= dtCurrentTable.Rows.Count)
you should try this (i < dtCurrentTable.Rows.Count)
because the counting of row is start from 0 and thats why you getting index out of range error.

Related

System.ArgumentOutOfRangeException: 'Specified argument was out of the range of valid values. Parameter name: index' in asp.net

Default.aspx
<Columns>
<asp:TemplateField HeaderText="Type">
<ItemTemplate>
<asp:DropDownList ID="typeHobby" runat="server">
<asp:ListItem style="display:none">--Select--</asp:ListItem>
<asp:ListItem Value="Sports">Sports</asp:ListItem>
<asp:ListItem Value="FineArt">Fine Arts</asp:ListItem>
<asp:ListItem Value="Other">Other</asp:ListItem>
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Name">
<ItemTemplate>
<asp:TextBox ID="nameSport" style="margin:2px" CssClass="cap" pattern="[A-Za-z]{2,15}" runat="server" ></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Details of participation">
<ItemTemplate>
<asp:TextBox ID="detailSport" style="margin:2px" CssClass="cap" pattern="[A-Za-z]{2,15}" runat="server"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Distinction achieved">
<ItemTemplate>
<asp:TextBox ID="distSport" style="margin:2px" CssClass="cap" pattern="[A-Za-z]{2,15}" runat="server"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Whether still intrested">
<ItemTemplate>
<asp:DropDownList ID="intrestSport" runat="server">
<asp:ListItem style="display:none">--Select--</asp:ListItem>
<asp:ListItem Value="yes">Yes</asp:ListItem>
<asp:ListItem Value="no">No</asp:ListItem>
</asp:DropDownList>
</ItemTemplate>
<FooterStyle HorizontalAlign="Right" />
<FooterTemplate>
<asp:Button ID="addHobby" runat="server" Text="Add" OnClick="ButtonAdd_Click_Hobby" CausesValidation="false" />
</FooterTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Default.aspx.cs
protected void ButtonAdd_Click_Hobby(object sender, EventArgs e)
{
addHobby();
}
protected void addHobby()
{
// MessageBox.Show("add hobby");
try
{
int rowIndex = 0;
if (ViewState["HoobyTable"] != null)
{
MessageBox.Show("if true");
DataTable dtHobbyTable = (DataTable)ViewState["HoobyTable"];
DataRow drHobbyRow = null;
if (dtHobbyTable.Rows.Count > 0)
{
MessageBox.Show(dtHobbyTable.Rows.Count.ToString());
for (int i = 1; i <= dtHobbyTable.Rows.Count; i++)
{
//extract the TextBox values
MessageBox.Show("loop");
DropDownList txh1 = (DropDownList)hobbyGrid.Rows[rowIndex].Cells[1].FindControl("typeHobby");
TextBox txh2 = (TextBox)hobbyGrid.Rows[rowIndex].Cells[2].FindControl("nameSport");
TextBox txh3 = (TextBox)hobbyGrid.Rows[rowIndex].Cells[3].FindControl("detailSport");
TextBox txh4 = (TextBox)hobbyGrid.Rows[rowIndex].Cells[4].FindControl("distSport");
DropDownList txh5 = (DropDownList)hobbyGrid.Rows[rowIndex].Cells[5].FindControl("intrestSport");
MessageBox.Show("Hello" + txh1.Text);
drHobbyRow = dtHobbyTable.NewRow();
drHobbyRow["Slno"] = i + 1;
dtHobbyTable.Rows[i - 1]["hoType"] = txh1.Text;
dtHobbyTable.Rows[i - 1]["Name"] = txh2.Text;
dtHobbyTable.Rows[i - 1]["Detail"] = txh3.Text;
dtHobbyTable.Rows[i - 1]["Distinction"] = txh4.Text;
dtHobbyTable.Rows[i - 1]["Interest"] ="interest";
rowIndex++;
}
dtHobbyTable.Rows.Add(drHobbyRow);
ViewState["HoobyTable"] = dtHobbyTable;
hobbyGrid.DataSource = dtHobbyTable;
hobbyGrid.DataBind();
}
}
else
{
Response.Write("ViewState is null");
}
}
catch (Exception e)
{
// MessageBox.Show(e.ToString());
}
//Set Previous Data on Postbacks
SetPreviousDataHobby();
}
private void SetPreviousDataHobby()
{
int rowIndex = 0;
if (ViewState["HoobyTable"] != null)
{
DataTable dt = (DataTable)ViewState["HoobyTable"];
if (dt.Rows.Count > 0)
{
for (int i = 0; i < dt.Rows.Count; i++)
{
DropDownList txh1 = (DropDownList)hobbyGrid.Rows[rowIndex].Cells[1].FindControl("typeHobby");
TextBox txh2 = (TextBox)hobbyGrid.Rows[rowIndex].Cells[2].FindControl("nameSport");
TextBox txh3 = (TextBox)hobbyGrid.Rows[rowIndex].Cells[3].FindControl("detailSport");
TextBox txh4 = (TextBox)hobbyGrid.Rows[rowIndex].Cells[4].FindControl("distSport");
DropDownList txh5 = (DropDownList)hobbyGrid.Rows[rowIndex].Cells[5].FindControl("intrestSport");
MessageBox.Show("type hobby" + dt.Rows[i]["hoType"].ToString());
txh1.Text = dt.Rows[i]["hoType"].ToString();
txh2.Text = dt.Rows[i]["Name"].ToString();
txh3.Text = dt.Rows[i]["Detail"].ToString();
txh4.Text = dt.Rows[i]["Distinction"].ToString();
txh5.Text = dt.Rows[i]["Interest"].ToString();
rowIndex++;
}
}
}
}
System.ArgumentOutOfRangeException: 'Specified argument was out of the range of valid values.
Parameter name: index'
-> got an error like above in line:
DropDownList txh5 = (DropDownList)hobbyGrid.Rows[rowIndex].Cells[5].FindControl("intrestSport");
(line from SetPreviousDataHobby() function)
I believe this should point you in the right direction
Rows and Columns of DataGrid starts at index 0
hobbyGrid.Rows[rowIndex].Cells[5] indicates that there are 6 columns, do you think that's true ?
The error message simply indicates that you are accessing an index that is outside the limits of the data structure.
You can validate how many columns are available at row[0] by hobbyGrid.Rows[0].Cells.Count-1; Cells[5] should not exceed this
OR
You can also check number of colums from table like int cols= dtHobbyTable.Columns.Count
Error is because, you are accessing cells from 1 through 5. so at Cells[5] its throwing out of range exception. Please modify your code to start from 0:
DropDownList txh1 = (DropDownList)hobbyGrid.Rows[rowIndex].Cells[0].FindControl("typeHobby");
TextBox txh2 = (TextBox)hobbyGrid.Rows[rowIndex].Cells[1].FindControl("nameSport");
TextBox txh3 = (TextBox)hobbyGrid.Rows[rowIndex].Cells[2].FindControl("detailSport");
TextBox txh4 = (TextBox)hobbyGrid.Rows[rowIndex].Cells[3].FindControl("distSport");
DropDownList txh5 = (DropDownList)hobbyGrid.Rows[rowIndex].Cells[4].FindControl("intrestSport");
Side but related notes:
1) There is another issue that you may encounter after fixing this error:
adding data row outside forloop. So, you are basically overwriting data row in for loop and adding just one row. Ignore me if that is what you expected. Otherwise, move the below line inside for loop.
dtHobbyTable.Rows.Add(drHobbyRow);
2) Another issue is you are running for loop on an item which you are updating. Instead its good to have for loop on hobbyGrid.Rows.Count.

Checkbox field not visible in gridview

I am working in asp.net. Trying to display data in gridview retrieved from a web service. I want five fields in gridview, one checkbox field and other four are values from service i.e.
CheckboxField,FirstName,LastName,OffenseName,FineAmount
1 ) Following is gridview code, that i just dragged and dropped into page
<asp:GridView ID="GridView1" runat="server">
<HeaderStyle BackColor="#CCFF33" />
</asp:GridView>
2 ) Following is my method that i call, to create fields in a DataTable, which i will bind to gridview later.
DataTable table = new DataTable();
table.Columns.Add("Select", typeof(CheckBox)); // i think problem is here
table.Columns.Add("FirstName", typeof(string));
table.Columns.Add("LastName", typeof(string));
table.Columns.Add("OffenseName", typeof(string));
table.Columns.Add("FineAmount", typeof(string));
3) Following is code to that populates the data table, with data
for (int i = 0; i < noOfContacts; i++)
{
object[] rowVals = new object[5];
rowVals[0] = giveCheckBox(i); // this method is declared below, which gives me a checkbox with unique id
rowVals[1] = listOfContacts[i].FirstName;
rowVals[2] = listOfContacts[i].LastName;
rowVals[3] = listOfCharges[j].GHQOffenseId;
rowVals[4] = listOfCharges[j].GHQFineAmount;
table.Rows.Add(rowVals);
}
GridView1.DataSource = table;
GridView1.DataBind();
4) This is method that gives me a checkbox, with unique id
public CheckBox giveCheckBox(int i)
{
CheckBox chk = new CheckBox();
chk.ID = "chk_" + i;
chk.Text = "Pay";
return chk;
}
Problem is that when i run the program, it only display four fields but not first checkbox field. I want to dispay that must.
But if i add checkbox field in designing view, (click arrow on gridview, click Add New Fields), then it throws exception at binding line i.e.
GridView1.DataBind();
Please guide me how to make checkbox field visible.
You can insert all your fields in design like code below :
<asp:GridView ID="GridView1" runat="server">
<HeaderStyle BackColor="#CCFF33" />
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox runat="server" ID="chk_box" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" />
<asp:BoundField DataField="OffenseName" HeaderText="OffenseName" />
<asp:BoundField DataField="FineAmount" HeaderText="FineAmount" />
</Columns>
</asp:GridView>
and for the code behind:
DataTable table = new DataTable();
for (int i = 0; i < 2; i++)
{
DataRow dr = table.NewRow();
dr["FirstName"] = "Ahmed";
dr["LastName"] = "Ahmed";
dr["OffenseName"] = "Ahmed";
dr["FineAmount"] = "Ahmed";
table.Rows.Add(dr);
}
GridView1.DataSource = table;
GridView1.DataBind();
Instead adding the checkbox to your table(which is wrong anyway) add a template field to the gridview as below. Also specify AutoGenerateColumns=true. Then remove all the code in your codebehind which tries to add checkbox column to the table and gridview.
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="True">
<Columns>
<asp:TemplateField ShowHeader="False" >
<ItemTemplate>
<asp:CheckBox ID="checkBoxSelect" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<HeaderStyle BackColor="#CCFF33" />
</Columns>
</asp:GridView>
Yes, you're right the problem lies exactly in that code snippet. Replace the following line
table.Columns.Add("Select", typeof(CheckBox));
with this one
table.Columns.Add("Select", typeof(bool));

ASP.NET c# Checkboxlist in a template field

I a newbie to asp.net. I have created a DB table in sqlserver with 3 columns; ImageID, Filename & Score.
FileName is C:\pics\beads.png or C:\pics\moreimages\scenary.jpeg.
Using C# asp.net, I have created a GridView. This Gridview should populate
(column 1)ImageID and get the image from the Filename (column2) and I have 2 Checkboxlist created as shown below which should accept score for the images from user and save it into the DB table.
Question 1 .
I am able to populate Image ID, but Images are not getting populated.
Question 2.
I do not know how to access the checkboxlist since it is in template. The checked is in the default select and doesn't change even if I click on it. Which method/property should be used to do save the selection to the database. Here's my code
<form id="form1" runat="server">
<p style="height: 391px">
<asp:GridView ID="GridView1" runat="server" Caption="Logos" Height="299px" Width="577px" AutoGenerateColumns="False">
<Columns>
<asp:BoundField DataField="ImageID" HeaderText="ImageID" />
<asp:ImageField DataImageUrlField="FileName" ControlStyle-Width="100"
ControlStyle-Height="100" HeaderText="Image" AlternateText="No image">
<ControlStyle Height="100px" Width="100px"></ControlStyle>
</asp:ImageField>
<asp:TemplateField HeaderText="Score" AccessibleHeaderText="CheckBoxList" ValidateRequestMode="Enabled">
<ItemTemplate>
<asp:CheckBoxList runat="server" AutoPostBack="true" RepeatColumns="3" ID="test">
<asp:ListItem Selected="True" Value="5">Good</asp:ListItem>
<asp:ListItem Value="0">Not Good </asp:ListItem>
<asp:ListItem Value="3">OK</asp:ListItem>
</asp:CheckBoxList>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Save" Width="130px" />
<asp:Button ID="Button2" runat="server" OnClientClick="javaScript:window.close(); return false;" Text="Exit" Width="102px" />
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</p>
</form>
public string sqlSel = #"SELECT TOP 3 [ImageID],FileName FROM [db1].[ImagesTest] where [Score] is null";
protected void Page_Load(object sender, EventArgs e)
{
using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["SQLConnectionString"].ConnectionString))
{
connection.Open();
SqlCommand cmdSel = new SqlCommand(sqlSel, connection);
SqlDataReader reader1 = cmdSel.ExecuteReader();
while (reader1.Read())
{
DataSet ds = GetData(sqlSel);
if (ds.Tables.Count > 0)
{
GridView1.DataSource = ds;
GridView1.DataBind();
}
else
{
Response.Write("Unable to connect to the database.");
}
}
}
}
private DataSet GetData(string cmdSel)
{
String strConnString = System.Configuration.ConfigurationManager.ConnectionStrings["SQLConnectionString"].ConnectionString;
DataSet ds = new DataSet();
try
{
SqlConnection con = new SqlConnection(strConnString);
SqlDataAdapter sda = new SqlDataAdapter(cmdSel,con);
sda.Fill(ds);
}
catch (Exception ex)
{
Response.Write("IN EXCEPTION "+ex.Message);
return null;
}
return ds;
}
Thanks for ur time
Rashmi
There are several issues with your code, here is what it should be fixed:
How to fix the images (Question 1)
As #Guilherme said in the comments, for images use URLs instead of disk paths.
Replace the images disk paths C:\pics\beads.png or C:\pics\moreimages\scenary.jpeg to something like Images/beads.png and Images/scenary.jpeg.
For this to work, you will need to have a folder named Images that contains these two files on the same directory level as your .aspx file.
Adjust your GridView1 declaration in the ASPX file
On your GridView1 declaration you should:
attach a handler to the OnRowDataBound event. This will allow you to properly bind the Score dataset column to the Score gridview column
set the DataKeyNames property on the grid to what should be the primary key for your images table (in this case DataKeyNames="ImageID")
use a RadioButtonList instead of a CheckboxList, because according to your dataset you can only set one value, which is what the RadioButtonList does. The CheckboxList is normally used when multiple selection is needed.
attach a handler to the SelectedIndexChanged event on the RadioButtonList. This will allow you to save the new values to the database (Question 2)
Here's how your GridView declaration should look like:
<asp:GridView ID="GridView1" runat="server" Caption="Logos" Height="299px" Width="577px" AutoGenerateColumns="False" OnRowDataBound="GridView1_RowDataBound" DataKeyNames="ImageID">
<Columns>
<asp:BoundField DataField="ImageID" HeaderText="ImageID" />
<asp:ImageField DataImageUrlField="FileName" ControlStyle-Width="100"
ControlStyle-Height="100" HeaderText="Image" AlternateText="No image">
<ControlStyle Height="100px" Width="100px"></ControlStyle>
</asp:ImageField>
<asp:TemplateField HeaderText="Score" AccessibleHeaderText="RadioButtonList" ValidateRequestMode="Enabled">
<ItemTemplate>
<asp:RadioButtonList runat="server" AutoPostBack="true" RepeatColumns="3" ID="test" OnSelectedIndexChanged="test_SelectedIndexChanged">
<asp:ListItem Value="5">Good</asp:ListItem>
<asp:ListItem Value="0">Not Good </asp:ListItem>
<asp:ListItem Value="3">OK</asp:ListItem>
</asp:RadioButtonList>
<!-- UPDATED! - keep the old values in a hidden field -->
<asp:HiddenField runat="server" ID="hfOldScore" Value='<%# Eval("Score") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Adjust your code behind value in your .ASPX.CS file (Question 2)
On the code behind, you will also need to:
Make sure you are binding to the GridView only once in the Page_Load event, by checking the IsPostBack property
(Optional, but recommended) Move the logic of getting data (with the SQLConnection code) in a separate method that will handle only data retrieval
Implement the handler for the OnRowDataBound event. This will bind any values from the Score column to the RadioButtonList control
Implement the handler for the SelectedIndexChecked event of the RadioButtonList control. This will allow you to save to the database the new values
Finally, here's the entire code-behind code:
protected void Page_Load(object sender, EventArgs e)
{
//bind only the first time the page loads
if (!IsPostBack)
{
DataSet ds = GetData(sqlSel);
if (ds.Tables.Count > 0)
{
GridView1.DataSource = ds;
GridView1.DataBind();
}
else
{
Response.Write("Unable to connect to the database.");
}
}
}
private DataSet GetData(string cmdSel)
{
//normally you should query the data from the DB
//I've manually constructed a DataSet for simplification purposes
DataSet ds = new DataSet();
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("ImageID", typeof(int)));
dt.Columns.Add(new DataColumn("FileName", typeof(string)));
dt.Columns.Add(new DataColumn("Score", typeof(int)));
dt.Rows.Add(100, #"Images/beads.png", 0);
dt.Rows.Add(200, #"Images/moreimages/scenary.jpeg", 3);
dt.Rows.Add(300, #"Images/moreimages/scenary.jpeg", 5);
ds.Tables.Add(dt);
return ds;
}
protected void Button1_Click(object sender, EventArgs e)
{
//UPDATED - iterate through all the data rows and build a dictionary of items
//to be saved
Dictionary<int, int> dataToUpdate = new Dictionary<int, int>();
foreach (GridViewRow row in GridView1.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
int imageID = (int)GridView1.DataKeys[row.RowIndex].Value;
int oldScore;
int newScore;
int.TryParse((row.FindControl("hfOldScore") as HiddenField).Value, out oldScore);
int.TryParse((row.FindControl("test") as RadioButtonList).SelectedValue, out newScore);
if (oldScore != newScore)
{
dataToUpdate.Add(imageID, newScore);
}
}
}
//update only the images that were changed
foreach (var keyValuePair in dataToUpdate)
{
SaveToDB(keyValuePair.Key, keyValuePair.Value);
}
}
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
//we are only interested in the data Rows
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataRow dataRow = (e.Row.DataItem as DataRowView).Row;
//manually bind the Score column to the RadioButtonlist
int? scoreId = dataRow["Score"] == DBNull.Value ? (int?)null : (int)dataRow["Score"];
if (scoreId.HasValue)
{
RadioButtonList test = e.Row.FindControl("test") as RadioButtonList;
test.ClearSelection();
test.SelectedValue = scoreId.Value.ToString();
}
}
}
protected void test_SelectedIndexChanged(object sender, EventArgs e)
{
RadioButtonList test = sender as RadioButtonList;
GridViewRow gridRow = test.NamingContainer as GridViewRow;
//obtain the current image Id
int imageId = (int)GridView1.DataKeys[gridRow.RowIndex].Value;
//obtain the current selection (we will take the first selected checkbox
int selectedValue = int.Parse(test.SelectedValue);
//UPDATED! - saves are now handled on the Save button click
//SaveToDB(imageId, selectedValue);
}
private void SaveToDB(int imageId, int score)
{
//UPDATED!
using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["SQLConnectionString"].ConnectionString))
{
connection.Open();
using (SqlCommand command = connection.CreateCommand())
{
command.Parameters.Add("#ImageID", imageId);
command.Parameters.Add("#Score", score);
command.CommandText = #"update [db1].[ImagesTest] set Score = #Score where [ImageID] = #ImageID";
command.ExecuteNonQuery();
}
}
}
UPDATED!
The declaration of the GridView1 now contains a hidden field containing the Score value. You can use this hidden field to determine which row has changed, so you can trigger a save only on the changed ones
Save is now done on the click of the Save button, by iterating through the rows of the grid an building a Dictionary<int,string> to keep only the changes.
SaveToDB method should work, but I cannot test this myself.
Question 2:
To access your checkbox you can use.
GridViewRow row = GridView1.Rows[i];
CheckBox Ckbox = (CheckBox)row.FindControl("test");
For Question 1
Instead of ImageField you can use use ASP:Image in Templatefield like this
<asp:TemplateField HeaderText="Score" AccessibleHeaderText="CheckBoxList" ValidateRequestMode="Enabled">
<ItemTemplate>
<asp:Image ID="imageControl" runat="server" ImageUrl='<%# Eval("Filename") %>'></asp:Image>
</ItemTemplate>
</asp:TemplateField>
For Question 2
This is one of the example for how to access each Checkbox list inside gridview
For Each gvr As GridViewRow In Gridview1.Rows
If (CType(gvr.FindControl("CheckBox1"), CheckBox)).Checked = True Then
ReDim uPrimaryid(iCount)
uPrimaryid(iCount) = New Integer
uPrimaryid(iCount) = gvr.Cells("uPrimaryID").Text
iCount += 1
End If
Next

Grid view row command is firing after every second click

I've shopping cart in grid view. The grid is in update panel with update mode always. The grid view is itself in a user control and this user control renders in a child page (GridView --> User Control --> Child aspx page --> master page). Whenever I click on any button to modify cart the gridview row command not fires first time but when I again click on the button second time the row command fires correctly. Now I don't know why the row command event is not firing on first click and it is firing only on every even click (second click).
ASP:
<asp:GridView ID="GVCart" runat="server" AutoGenerateColumns="False" OnRowCommand="CartUpdate">
<Columns>
<asp:BoundField DataField="Product_Name" HeaderText="Product Name">
</asp:BoundField>
<asp:TemplateField>
<ItemTemplate>
<asp:ImageButton ID="Button3" runat="server" CommandArgument='<%# Eval("Product_ID") %>'
CommandName="DecreseCartQty" Height="20px" ToolTip="Minus" AlternateText="+" />
<asp:ImageButton ID="ImageButton1" runat="server" CommandArgument='<%# Eval("Product_ID") %>'
CommandName="IncreaseCartQty" Height="20px" ToolTip="Add" AlternateText="-" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="ABC" runat="server" Text='<%# Eval("ItemQTY")+" * "+Eval("Price")+" = "+Eval("TotalPrice") %> '></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:ImageButton ID="Button4" runat="server" CommandArgument='<%# Eval("Product_ID") %>' CommandName="Remove" ToolTip="Cancel"/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
C#: (in user control)
protected void CartUpdate(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "IncreaseCartQty")
{
int ProductId = Convert.ToInt32(e.CommandArgument.ToString());
DataTable CartDT = (DataTable)Session["cart"];
for (int i = 0; i < CartDT.Rows.Count; i++)
{
if (CartDT.Rows[i]["Product_ID"].ToString() == ProductId.ToString())
{
CartDT.Rows[i]["ItemQTY"] = Convert.ToInt32(CartDT.Rows[i]["ItemQTY"]) + 1;
CartDT.Rows[i]["TotalPrice"] = Convert.ToInt32(CartDT.Rows[i]["Price"]) * Convert.ToInt32(CartDT.Rows[i]["ItemQTY"]);
//Page.Response.Redirect(Page.Request.Url.ToString(), true);
}
}
}
if (e.CommandName == "DecreseCartQty")
{
int ProductId = Convert.ToInt32(e.CommandArgument.ToString());
DataTable CartDT = (DataTable)Session["cart"];
for (int i = 0; i < CartDT.Rows.Count; i++)
{
if (CartDT.Rows[i]["Product_ID"].ToString() == ProductId.ToString())
{
if (Convert.ToInt32(CartDT.Rows[i]["ItemQTY"]) > 1)
{
CartDT.Rows[i]["ItemQTY"] = Convert.ToInt32(CartDT.Rows[i]["ItemQTY"]) - 1;
CartDT.Rows[i]["TotalPrice"] = Convert.ToInt32(CartDT.Rows[i]["Price"]) * Convert.ToInt32(CartDT.Rows[i]["ItemQTY"]);
// Page.Response.Redirect(Page.Request.Url.ToString(), true);
}
}
}
}
if (e.CommandName == "Remove")
{
int ProductId = Convert.ToInt32(e.CommandArgument.ToString());
DataTable CartDT = (DataTable)Session["cart"];
for (int i = 0; i < CartDT.Rows.Count; i++)
{
if (CartDT.Rows[i]["Product_ID"].ToString() == ProductId.ToString())
{
CartDT.Rows.RemoveAt(i);
//Page.Response.Redirect(Page.Request.Url.ToString(), true);
}
}
}
}
Can anyone tell me what wrong I am doing. Your answer will be great help for me.
Thanks in advance.
It is behaving properly. You should rebind the gridview after CartUpdate so that another post back is not required.
just add these lines after
if (e.CommandName == "Remove")
{
int ProductId = Convert.ToInt32(e.CommandArgument.ToString());
DataTable CartDT = (DataTable)Session["cart"];
for (int i = 0; i < CartDT.Rows.Count; i++)
{
if (CartDT.Rows[i]["Product_ID"].ToString() == ProductId.ToString())
{
CartDT.Rows.RemoveAt(i);
//Page.Response.Redirect(Page.Request.Url.ToString(), true);
}
}
}
DataTable CartDT = (DataTable)Session["cart"];
gridview1.datasource=CartDT ;
gridview1.databind();
Checkout this answer, I think it will solve your problem. If you have your grid view in user control this issue can arise. I had a same issue when I had my grid view in a user control.

Adding a drop down in itemtemplate and populating value dynamically

I have an item template in a GridView and I want to create a dropdown for each row and bind it to a value retrieved from the database.. but I am not sure how to do this.. this is what i have so far.. but not sure where to put the code to populate the drop down per row..
<ItemTemplate>
<asp:DropDownList runat="server" ID="ddlMyQuantity" SelectedValue='<%#
(DataBinder.Eval(Container.DataItem,"Quantity")) %>'>
</asp:DropDownList>
</ItemTemplate>
and in code behind, not sure how to or where to put this so that it is created on every row..
public void BindMyQuantity()
{
for (int i = 1; i < 15; i++)
{
ddlMyQuantity.Items.Add(i.ToString());
}
}
Also i am not sure if i can do that, but the code is not complaining.. adding SelectedValue in the asp declaration
You can use OnRowDataBound to dynamically bind your dropdown:
protected void GridView_RowDataBound(Object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
var dropdownList = (DropDownList)e.Row.FindControl("ddlMyQuantity");
for (int i = 1; i < 15; i++)
{
dropdownList.Items.Add(i.ToString());
}
dropdownList.SelectedValue =
Convert.ToString(DataBinder.Eval(e.Row.DataItem, "Quantity"));
}
}
Add binding:
<asp:GridView ... OnRowDataBound="GridView_RowDataBound">
...
</asp:GridView>
As per my knowledge, the best option would be to write this code in "RowDataBound" event of the Grid. See sample code below.
protected void GridView_RowDataBound(..)
{
if (e.Row.RowType.Equals(DataControlRowType.DataRow))
{
DropDownList ddl = e.Row.FindControl("ddlMyQuantity") as DropDownList;
if (ddl != null)
{
for (int i = 1; i < 15; i++)
{
ddl.Items.Add(i.ToString());
}
}
}
}
In the aspx page, provide this
<ItemTemplate>
<asp:DropDownList runat="server" ID="ddlMyQuantity"></asp:DropDownList>
</ItemTemplate>
Hope this Helps!!
<asp:TemplateField HeaderText="Type Cargo" HeaderStyle-HorizontalAlign="Center" ItemStyle-Width="10%" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:DropDownList ID="DropDownList1" runat="server" DataValueField="DESCRIPTION"></asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
Code Behind will look like this...
Dim rowId As DropDownList
For i As Integer = 0 To gridView1.Rows.Count - 1
Dim gridrow As GridViewRow = gridView1.Rows(i)
rowId = DirectCast(gridrow.FindControl("DropDownList1"), DropDownList)
Dim dt As DataTable = Get_List()
rowId.DataSource = dt
rowId.DataBind()
Next
Get_List is a Function that returns a DataTable

Categories