I am using a template to have create my gridview. I have have basically created a check box when once select creates a session variable and I then redirect the user to a separate page. The problem is the that the event is not firing off creating the wrapper.
The event:
void cmd1_Click(object sender, EventArgs e)
{
Button txtdata = (Button)sender;
inventoryBLL inv = new inventoryBLL();
GridViewRow gvr = (GridViewRow)txtdata.NamingContainer;
Label myControl = new Label();
TableCell tc = gvr.Cells[0];
// where GridView1 is the id of your GridView and indexOfCell is your index
foreach (Control c in tc.Controls)
{
if (c is Label)
{
myControl = (Label)c;
}
}
Label myControl1 = new Label();
List<string> shipmentnames = new List<string>();
List<string> asinlist = new List<string>();
List<string> fnskulist = new List<string>();
List<string> productlist = new List<string>();
shipmentnames.Add(inv.shipmentname(_ShipmentID));
asinlist.Add(myControl.Text);
asinwrapper asin1 = new asinwrapper(asinlist, fnskulist, productlist, 0);
asinwrapper.CreateSessionWrapper(asin1);
ShipmentWrapper.CreateSessionWrapper(new ShipmentWrapper(shipmentnames));
}
The code that I create the checkbox:
CheckBox cmd1 = new CheckBox();
cmd1.Text = "Change";
cmd1.CheckedChanged += new EventHandler(cmd1_Click);
cmd1.AutoPostBack = true;
container.Controls.Add(cmd1);
The code calling the template
bfield.HeaderTemplate = new GridViewTemplateShipmentItems(ListItemType.Header, "Change", FieldType.Label, ddlShipments.SelectedValue.ToString());
bfield.ItemTemplate = new GridViewTemplateShipmentItems(ListItemType.Item, "Change", FieldType.ButtonAdd, ddlShipments.SelectedValue.ToString());
grvList.Columns.Add(bfield);
bfield = new TemplateField();
Ok, so if I understood correctly, you have the checkbox embedded in a row of the Gridview, correct?
If so, you have to work with the gridview selected row event, (the checkbox events are now hidden and will not function as expected)
next find the checkbox
determine if the checkbox is checked
redirect the user.
I can get you more precise syntax if you like.
Related
I am creating a web app that allows the user to create their own forms. but once a control is added (for example a new label with its control) it will be deleted upon me trying to add another object to the form.
this is the code for the button that creates the new item.
protected void createFormButton_Click(object sender, EventArgs e)
{
////titles is the div id of where i want to insert the title label
var titlelabel = new Label();
titlelabel.Text = textboxForTitle.Text;
titles.Controls.Add(titlelabel);
controls.Add(titlelabel);
if (optionsDropdown.SelectedValue == "Checkbox")
{
//elements is the div id of where i want to insert the control
var newControl = new CheckBox();
newControl.CssClass = "checkbox";
newControl.Checked = true;
elements.Controls.Add(newControl);
controls.Add(newControl);
}
else if (optionsDropdown.SelectedValue == "Textbox")
{
//elements is the div id of where i want to insert the control
var newControl = new TextBox();
newControl.Text = "this is some text on the new box";
newControl.CssClass = "form-control";
elements.Controls.Add(newControl);
}
else if (optionsDropdown.SelectedValue == "Dropdown")
{
//elements is the div id of where i want to insert the control
var newControl = new DropDownList();
newControl.Items.Add("one");
newControl.Items.Add("two");
newControl.Items.Add("three");
newControl.CssClass = "form-control";
elements.Controls.Add(newControl);
}
}
how can I save the new controls, so with each button click they previous control does not get deleted on postback?
When adding controls dynamically they are deleted on each postback. Now if you follow the lifecycle of an asp page you will notice that the viewstate ( the variable that holds all of your data from the client side objects) comes after the page.init. So when working with dynamically added controls in asp you need to recreate then on each postback in the page.init event. Then the viewstate is loaded into thoses controls. The way i do it is i keep everycontrol created in a list(of control) in session and add them in the placeholder at the page.init
You could create a class-level variable which is a List of controls, rather than adding an item to the built-in controls collection. In your case you would need two, since you are adding controls both to the page and the elements div. These lists will persist across postbacks, so each time you can repopulate the page controls accordingly at the end of your method via AddRange.
NOTE: code untested.
List<Control> pageControls = new List<Control>();
List<Control> elementControls = new List<Control>();
protected void createFormButton_Click(object sender, EventArgs e)
{
////titles is the div id of where i want to insert the title label
var titlelabel = new Label();
titlelabel.Text = textboxForTitle.Text;
titles.Controls.Add(titlelabel);
pageControls.Add(titlelabel);
if (optionsDropdown.SelectedValue == "Checkbox")
{
//elements is the div id of where i want to insert the control
var newControl = new CheckBox();
newControl.CssClass = "checkbox";
newControl.Checked = true;
elements.Controls.Add(newControl);
pageControls.Add(newControl);
}
else if (optionsDropdown.SelectedValue == "Textbox")
{
//elements is the div id of where i want to insert the control
var newControl = new TextBox();
newControl.Text = "this is some text on the new box";
newControl.CssClass = "form-control";
elementControls.Add(newControl);
}
else if (optionsDropdown.SelectedValue == "Dropdown")
{
//elements is the div id of where i want to insert the control
var newControl = new DropDownList();
newControl.Items.Add("one");
newControl.Items.Add("two");
newControl.Items.Add("three");
newControl.CssClass = "form-control";
elementControls.Add(newControl);
}
Controls.AddRange(pageControls);
elements.Controls.AddRange(elementControls);
}
I have created dynamic controls on DropdownList's SelectedIndexChanged event. Button is one of those controls. I have also assigned event to that button but debugger is not coming on that click event. Following is my code.
protected void Page_Load(object sender, EventArgs e)
{
try
{
token = Session["LoginToken"].ToString();
if (!IsPostBack)
{
BindData();
fsSearch.Visible = false;
btnDownload.Visible = false;
}
else
{
foreach (HtmlTableRow row in (HtmlTableRowCollection)Session["dynamicControls"])
{
tblSearch.Rows.Add(row);
}
}
}
catch
{
}
}
private void BindData()
{
ddlReportName.DataSource = svcCommon.GetReports(token, out message);
ddlReportName.DataValueField = "Key";
ddlReportName.DataTextField = "Value";
ddlReportName.DataBind();
ddlReportName.Items.Insert(0, "--Select--");
}
protected void ddlReportName_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
string[] reportInfo = ddlReportName.SelectedValue.Split('|');
Session["dynamicControls"] = null;
tblSearch.Rows.Clear();
HtmlTableRow row = new HtmlTableRow();
HtmlTableCell cellFieldNameLbl = new HtmlTableCell();
HtmlTableCell cellFieldNameDdl = new HtmlTableCell();
HtmlTableCell cellOperatorLbl = new HtmlTableCell();
HtmlTableCell cellOperatorDdl = new HtmlTableCell();
HtmlTableCell cellValueLbl = new HtmlTableCell();
HtmlTableCell cellValueTxt = new HtmlTableCell();
HtmlTableCell cellOperatorRbtn = new HtmlTableCell();
HtmlTableCell cellAddMoreFilter = new HtmlTableCell();
Button btnAddMore = new Button();
DropDownList ddlColumn = new DropDownList();
DropDownList ddlOperator = new DropDownList();
TextBox txtValue = new TextBox();
RadioButtonList rbtnOperator = new RadioButtonList();
List<string> filterValues = svcCommon.GetSearchColumns(Convert.ToInt64(reportInfo[0]), token, out message);
fsSearch.Visible = btnDownload.Visible = filterValues.Count > 0 ? true : false;
ddlColumn.ID = "_ddlColumn0";
ddlOperator.ID = "_ddlOperator0";
txtValue.ID = "_txtValue0";
rbtnOperator.ID = "_rbtnOperator0";
btnAddMore.ID = "_btnAddMore0";
rbtnOperator.Items.Add("AND");
rbtnOperator.Items.Add("OR");
rbtnOperator.RepeatDirection = RepeatDirection.Horizontal;
btnAddMore.Text = "Add More";
btnAddMore.Click +=btnAddMore_Click;
ddlColumn.DataSource = filterValues;
ddlColumn.DataBind();
ddlOperator.DataSource = new List<string>()
{
"Equal",
"Not Equal",
"Less Than",
"Less Than Or Equal",
"Greater Than",
"Greater Than Or Equal",
"Start With",
"Not Start With",
"End With",
"Not End With",
"Contains",
"Not Contains",
"Between",
"Not Between",
"In",
"Not In"
};
ddlOperator.DataBind();
cellFieldNameLbl.InnerText = "Field Name:";
cellFieldNameDdl.Controls.Add(ddlColumn);
cellOperatorLbl.InnerText = "Operator";
cellOperatorDdl.Controls.Add(ddlOperator);
cellValueLbl.InnerText = "Value";
cellValueTxt.Controls.Add(txtValue);
cellOperatorRbtn.Controls.Add(rbtnOperator);
cellAddMoreFilter.Controls.Add(btnAddMore);
row.Cells.Add(cellFieldNameLbl);
row.Cells.Add(cellFieldNameDdl);
row.Cells.Add(cellOperatorLbl);
row.Cells.Add(cellOperatorDdl);
row.Cells.Add(cellValueLbl);
row.Cells.Add(cellValueTxt);
row.Cells.Add(cellOperatorRbtn);
row.Cells.Add(cellAddMoreFilter);
tblSearch.Rows.Add(row);
Session["dynamicControls"] = tblSearch.Rows;
}
catch (Exception ex)
{
}
}
protected void btnAddMore_Click(object sender, EventArgs e)
{
try
{
}
catch
{
}
}
The problem with dynamically created controls in asp.net webforms is that they aren't automatically added to the viewstate, so the postback event won't happen.
This should help you to understand adding controls dynamically, and managing them via the viewstate http://forums.asp.net/t/1900207.aspx?Creating+buttons+dynamically
Alternatively, a much easier way to manage this is to have the buttons on the page but not visible, then in the selected_index_changed event, just switch the visibility to true.
I hadn't enough time to try so many thing. The thing I did is stored the container on which dynamic controls are added into Session and on Page_Init event I have bound event and it is working fine now. :)
I have to display n grids, n is variable, then I dont know how many grids I'll have.
My problem is, I have to init this grids with Visible false and when click in a button show the grid specific for that button, then how can I link a button to a gridview?
My code that generate the grids:
foreach (List<DataRow> lst in grids)
{
dt = lst.CopyToDataTable();
GridView grv = new GridView();
grv.AlternatingRowStyle.BackColor = System.Drawing.Color.FromName("#cccccc");
grv.HeaderStyle.BackColor = System.Drawing.Color.Gray;
grv.ID = "grid_view"+i;
grv.Visible = false;
grv.DataSource = dt;
grv.DataBind();
Label lblBlankLines = new Label();
lblBlankLines.Text = "<br /><br />";
Label lblTipo = new Label();
string tipoOcorrencia = lst[0]["DESC_OCORRENCIA"].ToString();
tipoOcorrencia = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(tipoOcorrencia);
int quantidade = lst.Count;
lblTipo.Text = tipoOcorrencia + ": " + quantidade;
LinkButton lkBtn = new LinkButton();
lkBtn.ID = "link_button"+i;
lkBtn.Text = "+";
place_grids.Controls.Add(lblBlankLines);
place_grids.Controls.Add(lkBtn);
place_grids.Controls.Add(lblTipo);
place_grids.Controls.Add(grv);
place_grids.DataBind();
i++;
}
Thanks in advance.
Modify your foreach loop as below.
private void GenerateControls()
{
int i = 0;
foreach (List<DataRow> lst in grids)
{
dt = lst.CopyToDataTable();
GridView grv = new GridView();
grv.AlternatingRowStyle.BackColor = System.Drawing.Color.FromName("#cccccc");
grv.HeaderStyle.BackColor = System.Drawing.Color.Gray;
grv.ID = "grid_view" + i;
//grv.Visible = false;//Commented as the grid needs be generated on client side, in order to make it visible from JavaScript/jQuery
grv.Attributes.Add("style", "display:none;");
grv.DataSource = dt;
grv.DataBind();
//Adding dynamic link button
LinkButton lnkButton = new LinkButton();
lnkButton.Text = "button " + i;
//lnkButton.Click += new EventHandler(lnkButton_Click);
lnkButton.ID = "lnkButton" + i;
lnkButton.OnClientClick = "ShowGrid('" + grv.ClientID + "');";
Label lblTipo = new Label();
lblTipo.Text = "text " + i;
lblTipo.ID = "lbl" + i;
tempPanel.Controls.Add(lblTipo);
tempPanel.Controls.Add(grv);
tempPanel.Controls.Add(lnkButton);
tempPanel.DataBind();
i++;
}
}
Then you will have to add a link button click event as below, if you want server side event to fire. (Un-comment the line where event handler is assigned to link button.)
protected void lnkButton_Click(Object sender, EventArgs e)
{
LinkButton lnkButton = (LinkButton)sender;
String index = lnkButton.ID.Substring(lnkButton.ID.Length - 1);
GridView grv = (GridView)tempPanel.FindControl("grid_view" + index);
grv.Visible = true;
}
You will need to add all dynamically added controls in the Page_Init event for maintaining their state. Refer below links can be useful.
Dynamically Created Controls losing data after postback
ViewState in Dynamic Control
Call method GenerateControls from Page_Init event as below.
protected void Page_Init(object sender, EventArgs e)
{
GenerateControls();
}
EDIT :
JavaScript function...
function ShowGrid(gridID) {
document.getElementById(gridID).style.display = ''
}
I have kept the server side click event as it is. But I have commented the line where the event handler is assigned to the link button.
I have a GridView which holds user data. When the Page_Load Method is called, I get data using a DataTable and then bind it to the GridView. At the end of each row, I have added a CheckBox. This CB is used as a pointer for which entity the user wants to edit.
My problem is the Check_Changed Event of the CheckBoxes. I do not know how to add a handler if the control is generated programmatically. I also need the index of the row (a field value is also possible, but the column header and the column itself are hidden).
foreach (GridViewRow gvr in grdMitgliedsliste.Rows)
{
//add checkbox for every row
TableCell cell = new TableCell();
CheckBox box = new CheckBox();
cell.Controls.Add(box);
gvr.Cells.Add(cell);
//Hide columns for userid, status, etc.
gvr.Cells[0].Visible = false;
gvr.Cells[3].Visible = false;
gvr.Cells[4].Visible = false;
gvr.Cells[5].Visible = false;
gvr.Cells[8].Visible = false;
gvr.Cells[9].Visible = false;
}
I have already tried implementing the handler from here, but it gives me no index argument so the program cannot determine in which row the checkbox was checked.
protected void Page_Load(object sender, EventArgs e)
{
List<string> names = new List<string>();
names.Add("Jhonatas");
this.GridView1.DataSource = names;
this.GridView1.DataBind();
foreach (GridViewRow gvr in GridView1.Rows)
{
//add checkbox for every row
TableCell cell = new TableCell();
CheckBox box = new CheckBox();
box.AutoPostBack = true;
box.ID = gvr.Cells[0].Text;
box.CheckedChanged += new EventHandler(box_CheckedChanged);
cell.Controls.Add(box);
gvr.Cells.Add(cell);
}
}
void box_CheckedChanged(object sender, EventArgs e)
{
string test = "ok";
}
TableCell cell = new TableCell();
CheckBox box = new CheckBox();
box.Check += new EventHandler(Checked_Changed);
cell.Controls.Add(box);
gvr.Cells.Add(cell);
sorry, im allready about to drive home so its just an fast answer.
mabye you have to correct the event after box."event" ...
You should go this way:
first of all when you are generating the checkbox
CheckBox box = new CheckBox();
box.AutoPostBack=true;
provide an id to the checkbox as
box.ID=Convert.toString(Session["Count"]);
do initialize the "Count" when the page loads in the session.
also increment the "Count" everytime you add a new checkbox.
secondly, define the event handler for your dynamic check box like this:
box.CheckedChange += MyHandler;
and define the MyHandler
protected void MyHandler(object sender, EventArgs e)
{
//Do some stuff
}
now you may get the id for the checkbox from which the event has been fired inside the MyHandler, which will actually be the row number.
CheckBox cb = (CheckBox)sender;
string id = cb.ID;
I'm currently having a problem with event handlers assigned in the code-behind not appearing in the HTML code of the .aspx page. Below is the code fragment that does that:
HtmlTable table = new HtmlTable();
HtmlTableRow row = new HtmlTableRow();
foreach(XmlNode item in IDList)
{
LinkButton btn = new LinkButton();
btn.Text = item.InnerText;
btn.Click += new EventHandler(btn_Click);
HtmlTableCell cell = new HtmlTableCell();
cell.Controls.add(btn);
row.cells.add(cell);
}
table.rows.add(row);
Something like that, more or less. So when I run the page and inspected the buttons using FireBug, I noticed that the eventhandler names for the buttons created have been changed to the LinkButtons' unique ID(ct125, 126, 127, etc), I think, and not "btn_Click"
I'm hoping to hear if anyone else has faced this problem before and found a solution for it. Thanks.
your buttons might be using submit behavior for your buttons. Try setting "UseSubmitBehavior=false" for the buttons.
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.button.usesubmitbehavior.aspx
When creating controls dynamically, you should assign them Id also, otherwise asp.net will auto-assign them ids like ctl{somenumber}. Also, you need to recreate these controls on each postback, otherwise your eventhandlers will not work.
I was able to get this code to work as expected. I dynamically add 4 LinkButtons and wire the Click event to a function btn_Click. When I click each link, they call the btn_Click method server-side:
protected void Page_Load(object sender, EventArgs e)
{
HtmlTable table = new HtmlTable();
HtmlTableRow row = new HtmlTableRow();
for (int loop = 1; loop < 5; loop++)
{
LinkButton btn = new LinkButton();
btn.Text = "Test " + loop.ToString();
btn.Click += new EventHandler(btn_Click);
HtmlTableCell cell = new HtmlTableCell();
cell.Controls.Add(btn);
row.Cells.Add(cell);
}
table.Rows.Add(row);
// Add the table to a placeholder.
phInputs.Controls.Add(table);
}
protected void btn_Click(object sender, EventArgs e)
{
// Do something to catch a breakpoint.
var x = 10;
}
Ok, I got it fixed, but I'm absolutely bewildered at why it got fixed this way.
{
HtmlTable table = new HtmlTable();
HtmlTableRow row = new HtmlTableRow();
int btnIndex = 0;
foreach(XmlNode item in IDList)
{
LinkButton btn = new LinkButton();
btn.Text = item.InnerText;
btn.Click += new EventHandler(btn_Click);
btn.ID = "Btn_Page" + btnIndex.ToString();
HtmlTableCell cell = new HtmlTableCell();
cell.Controls.add(btn);
row.cells.add(cell);
}
table.rows.add(row);
}
protected void Btn_Page_0(object sender, EventArgs e)
{
whatever eventhandler code
}
When I inspected the HTML again, the names of the event handler assigned to the buttons are still being changed to its ID.
<a id="Btn_Page_0" href="javascript:_doPostback('Btn_Page_0','')">
So for each of those buttons, their event handlers are changed to Btn_Page_0, Btn_Page_1, Btn_Page_2, etc.
Strange thing is, they all go back to the Btn_Page_0 event handler when clicked, instead of btn_click
So.....yeah. Kinda boggles my mind why it worked like this, but it works anyhow...