I have this:
<asp:Table id="tbl_Items" runat="server">
</asp:Table>
<asp:Button ID="btn_AddNewItemField" runat="server" Text="Add New Item"
onclick="btn_AddNewItemField_Click" />
In PageLoad() I add one row:
TableRow row = new TableRow();
TableCell c1 = new TableCell();
c1.Controls.Add(new TextBox());
TableCell c2 = new TableCell();
c2.Controls.Add(new DropDownList());
row.Cells.Add(c1);
row.Cells.Add(c2);
this.tbl_Items.Rows.Add(row);
And this works.
But when I click on button to add new row I call this same code and code goes without errors but nothing happens. No error, no row, no nothing.
What am I doing wrong?
What you need is a little State management
try this
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
AddRow(true);
else
AddRows();
}
protected void btn_AddNewItemField_Click(object sender, EventArgs e)
{
AddRow(true);
}
void AddRow(bool addCounter)
{
TableRow row = new TableRow();
TableCell c1 = new TableCell();
c1.Controls.Add(new TextBox());
TableCell c2 = new TableCell();
c2.Controls.Add(new DropDownList());
row.Cells.Add(c1);
row.Cells.Add(c2);
this.tbl_Items.Rows.Add(row);
if (addCounter)
{
if (ViewState["rowCount"] == null)
ViewState["rowCount"] = 1;
else
{
int count = ((int)ViewState["rowCount"]);
ViewState["rowCount"] = ++count;
}
}
}
void AddRows()
{
if (ViewState["rowCount"] == null)
return;
int count = ((int)ViewState["rowCount"]);
for (int i = 1; i <= count; i++)
{
AddRow(false);
}
}
EDIT: The position will not change anything i think you have some other error; try this (this works for me):
<asp:Table id="tbl_Items" runat="server"></asp:Table>
<asp:Button ID="btn_AddNewItemField" runat="server" Text="Add New Item" />
protected void Page_Load(object sender, EventArgs e)
{
TableRow row = new TableRow();
TableCell c1 = new TableCell();
c1.Controls.Add(new TextBox());
TableCell c2 = new TableCell();
c2.Controls.Add(new DropDownList());
row.Cells.Add(c1);
row.Cells.Add(c2);
this.tbl_Items.Rows.Add(row);
btn_AddNewItemField.Click += new EventHandler(btnAddNewItemFieldClick);
}
void btnAddNewItemFieldClick(object sender, EventArgs e)
{
throw new NotImplementedException();
}
what is the code of "Page_Load"? This is probably due to a problem of "postback".
At one point the code returns to the "Page_load" function resets when you click a button..
Tried to include your code with "if (! IsPostBack) {}" in your Page_Load function to avoid problems.
like this..
Public void Page_Load()
{
if(!IsPostBack)
{
//....Your code
}
}
Related
I have a GridView and I am binding the grid dynamically . In this grid I want to make the 2nd cell as editable .I am able to do this , and after I modified the text boxes I will be clicking on the submit button . Here my issue is in button click event I am not able to get the textbox value.
code
<asp:GridView ID="DGridView" runat="server" Font-Size="Small" Width="40%" PageSize="4" ShowHeader="False" OnRowDataBound="DGridView_RowDataBound" AutoPostBack="True" />
protected void DGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
TextBox txtseed = new TextBox();
txtseed.ID = "txtseed";
txtseed.Text = Convert.ToString(DataBinder.Eval(e.Row.DataItem, "seed"));
e.Row.Cells[1].Controls.Add(txtseed);
}
}
protected void butSubmit_Click(object sender, EventArgs e)
{
for (int i = 0; i < DGridView.Rows.Count; i++)
{
strDNo = DGridView.Rows[i].Cells[0].Text;
dty = DGridView.Rows[i].Cells[1].FindControl("txtseed").ToString();
}
}
Here in dty is throwing error , can any one help?
Before getting text you need cast your object to TextBox. Don't forget set data source . You can follow this code it's working.
public class Test
{
public string Seed { get; set; }
}
protected void Page_Load(object sender, EventArgs e)
{
List<Test> test = new List<Test>();
test.Add(new Test() {Seed = "ssss"});
test.Add(new Test() { Seed = "aaaa" });
DGridView.DataSource = test;
DGridView.DataBind();
}
protected void DGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
TextBox txtseed = new TextBox();
txtseed.ID = "txtseed";
txtseed.Text = Convert.ToString(DataBinder.Eval(e.Row.DataItem, "seed"));
e.Row.Cells[0].Controls.Add(txtseed);
}
}
protected void Button1_OnClick(object sender, EventArgs e)
{
for (int i = 0; i < DGridView.Rows.Count; i++)
{
var strDNo = DGridView.Rows[i].Cells[0].Text;
TextBox dty =(TextBox)DGridView.Rows[i].Cells[0].FindControl("txtseed");
var z = dty.Text;
}
}
I my ASP.NET Webforms app, I have a table in which I add all data dynamically. One row contains Buttons in each cell. I want the button to fire onclick event when the user clicks on it. But, with the below code, the event never fires and the table disappears. Here's the code :
<asp:Table ID="floorTable" runat="server" Width="100%" GridLines="Both">
</asp:Table>
In Code behind
// This method is called on a DropDownList SelectedItemChanged Event - so
// the buttons cannot be created in Page_Load or so. Have to create
// totally based on the DropDown selected item.
private void PopulateFloorRow(int floorNo, FloorPattern fp)
{
int cols = fp.UnitPattern.Count;
// HEADER ROW
TableRow thead = new TableRow();
thead.Width = Unit.Percentage(100);
thead.TableSection = TableRowSection.TableHeader;
TableCell theadCell = new TableCell();
theadCell.ColumnSpan = cols;
Label title = new Label();
title.Text = "Floor # " + floorNo;
theadCell.Controls.Add(title);
thead.Controls.Add(theadCell);
TableRow planRow = GetFloorPlan(floorNo, fp);
TableRow tr = new TableRow();
TableCell tc = null;
int tcWidPerc = (int)fp.UnitPattern.Count / 100;
foreach (UnitPattern up in fp.UnitPattern)
{
tc = new TableCell();
Button imgBtn = new Button();
// On Adding BELOW Line - ERROR - 0x800a1391 - JavaScript runtime error: 'UnitLinkClicked' is undefined
//imgBtn.Attributes.Add("onClick", "UnitLinkClicked(this)");
imgBtn.CommandArgument = up.UnitPatternId.ToString(); // I want to know which button is pressed. So, sort of Tag
imgBtn.Click += new EventHandler(UnitLinkClicked);
imgBtn.BorderWidth = Unit.Pixel(10);
imgBtn.BorderColor = Color.Transparent;
imgBtn.Width = Unit.Percentage(100);
if (up.UnitNo != null)
{
imgBtn.Text = up.UnitNo;
}
tc.Controls.Add(imgBtn);
tr.Controls.Add(tc);
}
floorTable.Rows.Add(thead);
floorTable.Rows.Add(planRow);
floorTable.Rows.Add(tr);
// Create Footer
PopulateTableFooter(cols);
}
protected void UnitLinkClicked(object sender, EventArgs e)
{
Button btn = (Button)(sender);
string upId = btn.CommandArgument;
System.Diagnostics.Debug.WriteLine("LINK Button clicked Of UP ID :" + upId);
}
EDIT : CODE OF SELECTEDiNDEXCHANGED ADDED
My DropDown_SelectedIndexChanged Code :
protected void floorDropDownList_SelectedIndexChanged(object sender, EventArgs e)
{
if (selectedProject == null)
selectedProject = _db.Projects.Find(projectsList.SelectedValue);
System.Diagnostics.Debug.WriteLine("SELCTED Project = " + selectedProject.ProjectId);
// "Select Floor" is selected, so Hide floor Table
if (floorDropDownList.SelectedValue == "-1")
{
floorTable.Visible = false;
}
else
{
int floorNo = int.Parse(floorDropDownList.SelectedValue);
if (floorNo > 0)
{
PopulateFloorRow(floorNo, (FloorPattern)selectedProject.FloorPattern.ElementAt(floorNo - 1));
}
}
}
If I had selected "3" in my drop down, the table appears as expected. I click on a button and the table disappears, but the value in the drop down in still "3" only.
EDIT PART OVER
With the above code, I when I click on a button, the UnitLinkClicked event is never fired (I had added breakpoint) and the whole table disappears.
Can you say what problem can this be ? A button by default is meant to be AutoPostBack & it doesn't have that property too. What am I missing here and how to solve this. Am stuck on this since days and trying to figure out.
Any help is highly appreciated.
Thanks
You need to set an ID for your button. Without the ID the event will not be fired.
Button imgBtn = new Button();
imgBtn.ID = "imgBtn";
Also make sure that each button you add has a unique ID. You could probably concatenate the floor no. or any other fields to arrive at a unique name.
Also, the table will disappear unless, you manage that in your Page_Load. You need to reload the table if the DropDown has a selected index.
EDIT: Code Sample
.cs code
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
PopulateFloorRow();
}
}
protected void cmb_SelectedIndexChanged(object sender, EventArgs e)
{
PopulateFloorRow();
}
private void PopulateFloorRow()
{
floorTable.Rows.Clear();
for (int i = 0; i < 2; i++)
{
TableRow tableRow = new TableRow();
tableRow.Cells.Add(new TableCell());
tableRow.Cells.Add(new TableCell());
tableRow.Cells[0].Controls.Add(new Label() { Text = cmb.SelectedItem.Text });
Button button = new Button();
button.ID = "btn" + i.ToString();
button.Text = "Click";
button.Click += button_Click;
tableRow.Cells[1].Controls.Add(button);
floorTable.Rows.Add(tableRow);
}
}
void button_Click(object sender, EventArgs e)
{
throw new NotImplementedException();
}
.aspx code
<asp:DropDownList id="cmb" runat="server" OnSelectedIndexChanged="cmb_SelectedIndexChanged" AutoPostBack="true"><asp:ListItem>One</asp:ListItem><asp:ListItem>Two</asp:ListItem></asp:DropDownList>
<asp:Table ID="floorTable" runat="server" Width="100%" GridLines="Both">
</asp:Table>
I have created button in my cs file with the code as below, and try to fire the event handler for the button which inside the table. However, it does not function with it. May I know what should I do?
protected void feesinfo_Click(object sender, EventArgs e)
{
//Hidden field for checking in .aspx file
ClientScript.RegisterHiddenField("typeButton", "FEE_INFO");
System.Diagnostics.Debug.WriteLine("School Fees Details");
Table tbl = new Table();
for (int i = 0; i < 5; i++)
{
TableRow tRow = new TableRow();
Table1.Rows.Add(tRow);
for (int j = 1; j <= 6; j++)
{
TableCell tCell = new TableCell();
if (j == 4)
{
Button btn = new Button();
btn.CssClass = "btn btn-success";
btn.ID = "btndetails";
btn.Text = "400";
tCell.Controls.Add(btn);
btn.Click += new EventHandler(btnClick);
}
else
{
tCell.Text = "Row " + i + ", Cell " + j;
}
tRow.Cells.Add(tCell);
}
}
}
protected void btnClick(object sender, EventArgs e)
{
ClientScript.RegisterHiddenField("typeButton", "Details");
System.Diagnostics.Debug.WriteLine("School Fees Details");
mpe.Show();
}
I have this table in my Page.aspx
<asp:Table ID="table1" runat="server" CssClass="tabla" ></asp:Table>
I am building dynamically table1 in my Page.aspx.cs from a list using a foreach, adding 3 cells:
TableCell cell_name = new TableCell();
cell_name.Text = "Some name";
TableCell cell_active = new TableCell();
CheckBox checkbox = new CheckBox();
cell_active.Controls.Add(checkbox);
TableCell cell_actions = new TableCell();
ImageButton button = new ImageButton();
cell_actions.Controls.Add(button);
TableRow row = new TableRow();
row.Cells.Add(cell_name);
row.Cells.Add(cell_active);
row.Cells.Add(cell_actions);
table1.Rows.Add(row);
I want my ImageButton to have a onClick event and get from there the table row id (index inside the table) for the parent row of my ImageButton that was clicked. Is that possible? Any ideas?
Try this:
protected void Page_Load(object sender, EventArgs e)
{
for (int i = 0; i < 3; i++)
{
TableCell cell_name = new TableCell();
cell_name.Text = "Some name";
TableCell cell_active = new TableCell();
CheckBox checkbox = new CheckBox();
cell_active.Controls.Add(checkbox);
TableCell cell_actions = new TableCell();
ImageButton button = new ImageButton();
button.CommandArgument=i.ToString();
button.Click += RowClick;
cell_actions.Controls.Add(button);
TableRow row = new TableRow();
row.Cells.Add(cell_name);
row.Cells.Add(cell_active);
row.Cells.Add(cell_actions);
table1.Rows.Add(row);
}
}
protected void RowClick(object sender, EventArgs e)
{
int rowIndex =int.Parse( ((ImageButton)sender).CommandArgument);
Response.Write("RowIndex = " + rowIndex);
}
In the click event handler:
ImageButton btn = sender as ImageButton;
TableCell tc = btn.Parent as TableCell;
TableRow tr = tc.Parent as TableRow;
This is how to add click event handler
button .Click += new ImageClickEventHandler(button _Click);
..
void button _Click(object sender, ImageClickEventArgs e)
{
......
Other possible solution besides using CommandArgument attribute in the clicked Control:
protected void btn_Click(object sender, EventArgs e)
{
ImageButton button = sender as ImageButton;
TableCell cell = button.Parent as TableCell;
TableRow row = cell.Parent as TableRow;
int index = table1.Rows.GetRowIndex(row);
}
index variable gets the row index in table1. This solution is based on the answer given by #Aheho.
Even though there is already an accepted answer, a more generic solution not requiring any control tagging - given any Control which could be a TableRow or anything contained within one, call this method from an OnClick event or wherever.
int GetRowIndexFromControl(Control control)
{
Table table = null;
TableRow row = null;
while(control != null && (table == null || row == null))
{
if (row == null) row = control as TableRow;
if (table == null) table = control as Table;
control = control.Parent;
}
return row == null || table == null ? -1 : table.Rows.GetRowIndex(row);
}
protected void btn_Click(object sender, EventArgs e)
{
int rowIndex = GetRowIndexFromControl(sender as Control);
if (rowIndex != -1)
{
// Do something with rowIndex
}
}
I created dynamically some textboxes. They are created after click on one button(number of the textboxes depends on the user).
protected void Button1_Click(object sender, EventArgs e)
{
int i = Convert.ToInt32(TextBox2.Text);
Table tbl = new Table();
tbl.Width = Unit.Percentage(80);
TableRow tr;
TableCell tc;
TextBox txt;
CheckBox cbk;
DropDownList ddl;
Label lbl;
Button btn;
for (int j = 1; j <= i; j++)
{
tr = new TableRow();
tc = new TableCell();
tc.Width = Unit.Percentage(25);
lbl = new Label();
lbl.Text = "Pitanje:";
tc.Controls.Add(lbl);
tr.Cells.Add(tc);
tc.Width = Unit.Percentage(25);
txt = new TextBox();
txt.ID = "txt_p_" + j;
tc.Controls.Add(txt);
tr.Cells.Add(tc);
tc.Width = Unit.Percentage(25);
lbl = new Label();
lbl.Text = "Odgovori:";
tc.Controls.Add(lbl);
tr.Cells.Add(tc);
tc.Width = Unit.Percentage(25);
txt = new TextBox();
txt.ID = "txt_o_" + j;
tc.Controls.Add(txt);
tr.Cells.Add(tc);
tbl.Rows.Add(tr);
}
Panel1.Controls.Add(tbl);
}
now I need to get the text that is typed into that textboxes. I tried with something that I found on the internet but can't get it to work.
protected void SpremiPitanja(object sender, EventArgs e)
{
int i = Convert.ToInt32(TextBox2.Text);
for (int j = 1; j <= i; j++)
{
***************************************
}
}
any kind of help is welcome. if you need more information I will give them
A variable declared in a function is only visible in a function. You need to store the TextBoxes in a variable, that exists even when the code in the function has "finished". For more information search for scopes.
Here is a small sample that stores TextBoxes in a List that is visible in your class.
Another option would be to use eventhandlers. It depends on your scenario, which solution would be suited better. If you store the TextBoxes in a List, you can easily perform clean up code (for instance remove EventHandlers if required). You can obviously combine Approach 1 and 2. In that case you would store the created TextBox in a List (or any other collection), but you would still use the sender in the eventhandler to get a reference to the sending TextBox.
public partial class Form1 : Form
{
List<TextBox> textBoxes = new List<TextBox>();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//Approach 1: create and add textbox to list
TextBox createdTextbox = new TextBox();
textBoxes.Add(createdTextbox);
}
private void button2_Click(object sender, EventArgs e)
{
//use the textboxes from the list
foreach(TextBox t in textBoxes)
{
//do something with t
}
}
private void button3_Click(object sender, EventArgs e)
{
//Approach 2: use eventhandlers and don't store textbox in a list
TextBox createdTextbox = new TextBox();
createdTextbox.TextChanged += createdTextbox_TextChanged;
listBox1.Items.Add(createdTextbox);
}
void createdTextbox_TextChanged(object sender, EventArgs e)
{
TextBox t = sender as TextBox;
if (t == null)
throw new ArgumentException("sender not of type TextBox", "sender");
//do something with t
}
}
You add textboxes the same way you do, this is my example (sorry it's vb.net):
Dim t As New TextBox With {.ID = "txt_123", .Text = "Vpiši"}
PlaceHolder1.Controls.Add(t)
t = New TextBox With {.ID = "txt_456", .Text = "Briši"}
PlaceHolder1.Controls.Add(t)
And then you iterate through controls in Placeholder (in my example):
Dim tItem As TextBox
Dim tValue As String = String.Empty
For Each c As Control In PlaceHolder1.Controls
If TypeOf c Is TextBox Then
tItem = c
tValue = tItem.Text.ToString
End If
Next
C# example added
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
TextBox t = new TextBox();
t.Text = "Vpiši";
t.ID = "txt_123";
PlaceHolder1.Controls.Add(t);
t = new TextBox();
t.Text = "Briši";
t.ID = "txt_456";
PlaceHolder1.Controls.Add(t);
}
}
protected void Button1_Click(object sender, EventArgs e)
{
TextBox tItem;
String tValue;
foreach (Control c in PlaceHolder1.Controls)
{
if (c.GetType() == typeof(TextBox))
{
tItem = (TextBox)c;
tValue = tItem.Text;
}
}
}