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;
Related
I want to add some checkboxes at the beginning of every row in a table in the page_load: (I add them in a asp:placeholder)
protected void Page_Load(object sender, EventArgs e)
{
Table dtTable = new Table();
TableHeaderRow dtHeaderRow = new TableHeaderRow();
TableHeaderCell dtHeaderCheckbox = new TableHeaderCell();
dtHeaderCheckbox.Controls.Add(dtHeaderCkBox);
dtHeaderRow.Cells.Add(dtHeaderCheckbox);
foreach (DataColumn col in _ds.Tables[0].Columns)
{
TableHeaderCell dtHeaderCell = new TableHeaderCell();
dtHeaderCell.Text += col.ColumnName;
dtHeaderRow.Cells.Add(dtHeaderCell);
}
dtTable.Rows.Add(dtHeaderRow);
TableRow row;
for (int i = 0; i < _ds.Tables[0].Rows.Count; i++)
{
row = new TableRow();
TableCell dtCell = new TableCell();
CheckBox ckBox = new CheckBox();
ckBox.ID = "chkBox_" + _ds.Tables[0].Rows[i]["IDENTIFIER"].ToString();
ckBox.AutoPostBack = false;
ckBox.EnableViewState = false;
dtCell.Controls.Add(ckBox);
row.Cells.Add(dtCell);
for (int j = 0; j < _ds.Tables[0].Columns.Count; j++)
{
TableCell cell = new TableCell();
cell.Text = _ds.Tables[0].Rows[i][j].ToString();
row.Cells.Add(cell);
}
dtTable.Rows.Add(row);
}
phUnconfirmedDiv.Controls.Add(dtTable);
}
The problem is now, when the user press a submit button(and postback), I don't have access to my checkboxes:
protected void btnAccept_OnClick(object sender, EventArgs e)
{
List<CheckBox> chkList = new List<CheckBox>();
foreach (Control ctl in form1.Controls)
{
if (ctl is CheckBox)
{
if (ctl.ID.IndexOf("chkBox_") == 0)
{
chkList.Add((CheckBox)ctl);
}
}
}
ScriptManager.RegisterStartupScript(this, GetType(), "event", "alert('" + chkList.Count + "');", true);
}
Dynamically generated controls lost their state once they are rendered on view. And for you, to access them again in your code-behind, when your postbacks, you will have to re-create them and after that you will be able to manipulate them.
As far as getting the checked values of the checkboxes is concerned, you could try something like this. This might not be exact, should give an idea though.
This would be your check-box :
<input type="checkbox" id="yourId" name="selectedIds" value="someValue"/>
In your codebehind :
value = Request.Form["selectedIds"];
Hope this helps.
I now managed to solve this problem. Thanks all for your tips!
All checkboxes that are checked are sent through the postback. So the "easiest" way is to search for all parameters, sent in postback, that are beginning like "chkBox_" and then save them in a list/array. So I know which data should be updated in my database:
protected void btnAccept_OnClick(object sender, EventArgs e)
{
List<String> chkList = new List<String>();
// All checked checkboxes are sent via the postback. Save this parameters in a list:
foreach (string s in Request.Params.Keys)
{
if (s.ToString().IndexOf("chkBox_") == 0)
{
chkList.Add(s.ToString());
}
}
Is autopostback set to true on the user interface controls for the button? ei:
<telerik:RadButton runat="server" ID="rBtnRelease" Text="Release" Width="100px" OnClick="rBtnRelease_Click" AutoPostBack="False"/>
That's usually the common mistake when one tries to get data back and forth between the client and the server side.
I have an aspx page where I dynamically create checkboxes and add them to a panel from data in a SQL database. I need to have only one checkbox checked at a time. I have tried and googled just about everything but I cannot get the right answer. How would I go about getting that done.
My code for creating the checkboxes
public void CreateTimeSelection()
{
DataSet times = GetTimes();
int i = 0;
foreach (DataTable table in times.Tables)
{
foreach (DataRow row in table.Rows)
{
CheckBox chkTime = new CheckBox();
i += 1;
chkTime.ID = row["Time"].ToString();
chkTime.AutoPostBack = true;
chkTime.Text = row["Time"].ToString();
chkTime.CheckedChanged += new EventHandler(this.CheckChanged_click);
pnlTimeSlots.Controls.Add(chkTime);
pnlTimeSlots.Controls.Add(new LiteralControl("<br />"));
}
}
}
Code for Checkbox event handlers
protected void CheckChanged_click(object sender, EventArgs e)
{
CheckBox chkSelect = (CheckBox)sender;
if (chkSelect.Checked == true)
{
//set other checkboxes to false
}
}
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.
I am creating a gridview dynamically with a ButtonField and several BoundFields. ButtonField button type is LinkButton. If i run it the buttonclick triggers a post back but rowCommand is not triggered. It is not triggered even if i use AutogenerateSelectButton. The event is dyanamically bound. Code As follows:
protected void B_Search_Click(object sender, EventArgs e) //Search buttonclick that creates and displays the gridview
{
gd = getGridView(); //defines the gridview with columns and buttonfield
gd.DataSource = executeAdvanceSearch(); //retrieves data from DB as Dataset
gd.DataBind();
gd.RowCommand += new GridViewCommandEventHandler(gdView_RowCommand); //Rowcommand event binding
PlaceHolder1.Controls.Add(gd);
}
protected void gdView_RowCommand(object sender, GridViewCommandEventArgs e) //not getting triggered on postback
{
int index = Convert.ToInt32(e.CommandArgument);
GridView gdView = (GridView)sender;
if (e.CommandName == "IDClick")
{
//Do something
}
}
private GridView getGridView()
{
GridView gdView = new GridView();
gdView.AutoGenerateColumns = false;
gdView.AutoGenerateSelectButton = true;
string name;
string[] field = ZGP.BLL.Search.getResultFormat(Convert.ToInt32(DDL_ResultView.SelectedValue), out name); //Ignore. This jst gets columnNames
if (field.Count() != 0)
{
gdView.Columns.Add(getSelectButton()); //Adds linkbutton
foreach (string cName in field) //ignore. This adds columns.
if (!String.IsNullOrEmpty(cName))
{
gdView.Columns.Add(GV_DataColumn.getGridViewColumn((DataColumnName)Enum.Parse(typeof(DataColumnName), cName))); //Ignore. adds columns
}
}
return gdView;
}
private ButtonField getSelectButton()
{
ButtonField _bf = new ButtonField();
_bf.ButtonType = ButtonType.Link;
_bf.HeaderText = "ID";
_bf.DataTextField = "ID";
_bf.CommandName = "IDClick";
return _bf;
}
Thanks for the help.
if (e.CommandName=="CommandName")
{
int index = Convert.ToInt32(e.CommandArgument);
GridViewRow row = GridView1.Rows[index];
string boundFieldText= row.Cells[0].Text;
}
You'll need to create the grid view on each postback.
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...