Similar to this question here ASP.Net Dynamic Command Button Event Not Firing but with a slightly different problem.
Provided below is a (very) condensed version of my code.
protected void Page_Load(object sender, EventArgs e)
{
RenderDataItems();
}
private void RenderDataItems()
{
pnlDataItems.Controls.Clear()
DataTable dt = MyClass.GetAllData();
foreach (DataRow dr in dt.Rows)
{
Button b = new Button();
b.Command += new CommandEventHandler(SelectItem);
b.CommandArgument = dr["ID"].ToString();
b.ID = "btnData" + dr["ID"].ToString();
if (hdnDataListID.Value == dr["ID"].ToString())
{
b.Text = "Selected Item";
}
else
{
b.Text = "Pick This Item";
}
pnlDataItems.Controls.Add(b);
}
}
private void SelectItem(object sender, CommandEventArgs e)
{
hdnDataListID.Value = e.CommandArgument.ToString();
RenderDataItems();
}
private void EditSelectItem(int id)
{
MyClass mc = new MyClass(id);
hdnDataListID.Value = mc.ID.ToString();
RenderDataItems();
}
The method SelectItem is only called by the button controls rendered within the RenderDataItems method. The EditSelectItem is called by a separate control that is created dynamically, but does not require the altering that the buttons in the RenderDataItems method requires.
I've run the debugger and stepped through the code to see what happens. When the page is loaded, the RenderDataItems is called from the PageLoad and populates the panel with all of the buttons having "Pick This Text" (because the HiddenField control's value (hdnDataListID) has not been set).
The first time I click one of the buttons, the RenderDataItems from PageLoad fires, followed by the initial population of the buttons, the HiddenField's value is set to the ID, and the second RenderDataItems call happens from within the SelectItem method. The buttons are cleared, and recreated. The correct button has the "Selected Item" text.
The second time I click one of the buttons, the RenderDataItems from PageLoad fires, followed by the initial population of the buttons, but the SelectItem method never fires.
The third time I click one of the buttons, the same functionality happens as the 1st time. The 4th mimics the 2nd. The 5th mimics the 1st. And so on, and so on.
When using the EditSelectItem method from the controls not contained within the panel (it's a DataSource bound GridView row with buttons that calls this method), it does exactly as I'd expect and properly sets the selected / unselected buttons, with calls to both the RenderDataItems and the EditSelectItem method every time.
Any ideas?
P.S. I've already removed all of my AJAX on this page.
You should give your Button b an ID.
Related
I have dynamically created a button using a function I made which is meant to increase the value of another button created using a similar function. I'm able to retrieve the name of the dynamically created textbox, but since it is dynamically created, I can't reference it.
I've tried to pass the textbox through as a parameter, but it doesn't appear that I'm able to pass extra parameters:
Button ButtonDecreaseValue= addButton(ItemName, "-");
TextBox TextBoxItemAmount = addTextBox(ItemName, "0");
So, how would I change the value of textbox one when ButtonRemoveItem is clicked?
I've created an event handler for the button, like so:
ButtonIncreaseValue.Click += new EventHandler(ItemDecreased);
But, inside the event handler, I'm unsure how I would change the textbox name.
private void ItemDecreased(object sender, EventArgs e)
{
Button currentItem = (Button)sender;
int ItemNo = Convert.ToInt32(currentItem.Tag);
DataRow ItemInfo = getItemDetails(ItemNo);
ItemInfo[0].ToString();
}
When clicking the button, the corresponding textbox should decrease in value.
Assuming this is Windows Forms
You said you have the name of the TextBox? You should be able to find it with that.
private void ItemDecreased(object sender, EventArgs e)
{
string textBoxName = HoweverYouGetTheDynamicTextBoxName();
// Assumptions:
// 1. ItemDecreased is a method on a Form or a UserControl.
// 2. There is only one TextBox with the given name in the Form or UserControl.
// 3. The TextBox is added to the Form or UserControl's Controls property.
TextBox tb = Controls.Find(textBoxName, true).OfType<TextBox>().SingleOrDefault();
if (tb is null)
{
// Couldn't find the text box for some reason.
}
// tb references the dynamically created text box.
}
i am programming a piece of software for a loyalty scheme. I have basically finished all of it. The only thing i am stuck on for ages is programming the buttons for the datagridview which i am using for my redeem offers page. I have gotten it to add a button to the end of each row automatically when you add a new offer but i am clueless on how to program it to recognize each row.
for e.g.)
Row1) Offer 1 is X name and costs Y
Row2) offer 2 is Z Name and costs F
I can only seem to find the ability to program every single button at once and not individual and even so, i need it to work automatically so when i can add a offer i can immediately purchase it. How would i get it to recognize which row i am on?
here is what my form and database looks like.
Picture Of Form - (picture link)
What my database looks like - (picture link)
below ur class
make public int id;
//adding button
DataGridViewButtonColumn col = new DataGridViewButtonColumn();
col.UseColumnTextForButtonValue = True;
col.Text = "ADD";
col.Name = "Btn_add";
DataGridView1.Columns.Add(col);
//pass id values here to do functions..
private void Btn_add_Click(object sender, EventArgs e)
{
}
//this gets selected index of selected row value
private void DataGridView1_SelectionChanged(object sender, EventArgs e)
{
int id = DataGridView1.SelectedRows(0).Cells(0).Value;
}
In Datagrid please bind OfferId in buy button. When press button then automatically gives id onclick event.
You can simply hook into the RowDataBound Event. This event is called, each time a new entry is put into the table. At this point, you can add a button to the tabe and add a custom action/url to the url.
I have a custom control that has a search function. When the user clicks search, the code generates a list of buttons based on the results of the search.
Each button's CommandArgument property contains the Id of the search result. When the user clicks the button, I want to handle the event, get the CommandArgument and raise an event back to the main page with the value.
The problem is that the buttons aren't raising the event. I would assume this is because it gets lost on a postback or whatever. Should I consider an alternative way of listing the values to make this work?
Whats the simplest way of getting around this? Here's what I have:
private void Search()
{
foreach (var c in companies)
{
TableRow companyRow = new TableRow();
TableCell nameRowCell = new TableCell();
TableCell regRowCell = new TableCell();
Button selectButton = new Button();
selectButton.CommandArgument = c.Id.ToString();
selectButton.Text = c.Name;
selectButton.Click += new EventHandler(selectButton_Click);
selectButton.CausesValidation = false;
nameRowCell.Controls.Add(selectButton);
companyRow.Cells.Add(nameRowCell);
tblCompanies.Rows.Add(companyRow);
}
}
void selectButton_Click(object sender, EventArgs e) // <- Not getting handled
{
Button btn = (Button)sender;
string id = btn.CommandArgument;
if (id != "" && CompanyFound != null)
CompanyFound(new Company() { Id = int.Parse(id) });
}
I've been playing with your code and it does put a button on the screen. The browser source shows the button in the form of an input type submit tag. To test that it is in fact firing add a div to your page somewhere, maybe set it's id to testDiv. Then in your selectButton_Click event hander add a line to the effect of: testDiv.innerHtml = "made it here".
If the div changes, your button fired.
Also, maybe add protected, public or something before the void on the selectButton_Click.
consider the following:
code for buttonclick fn in .cs file :
protected void additembtnClick(object sender, EventArgs e)
{
DataTable dt = createTemptable();
dt = (DataTable)Session["dfdtemptable"];
this.DFDLOVlst.DataSource = dt;
this.DFDLOVlst.DataBind();
this.txtLOVCode.Visible = true;
this.txtLOVvalue.Visible = true;
MDIngrdientsCode.Show();
}
this is the on_row clicked fn of the datagrid
protected void OnFindSelect(int Value)
{
}
code for findbtn click:
protected void btnFind_Click(object sender, EventArgs e)
{
this.FindLookup.SetLookup();
this.FindLookup.SearchLookup();
this.MdFindLookup.Show();
}
When the find button is clicked,the lookup control gets loaded with values from database.On selecting any row the selected row values will be added to corresponding text boxs and data grid.
The additembtnclick is to add new entry to the datagrid.The user can add new values or can click the find and select a row and update its values in the datagrid.
Theres no problem when the user adds fresh values .When the user click the find and select a particular row.The values gets add to correspondind fieldls..And now if the user clicks the additem button to add new values to already existing values in datagrid then the fn onfindselected(fn for the onrowclicked event for the lookup control containg datagrid) is called automatically,but the call is not in the button click fn..
Can't figure out whats wrong..?
It appears that theOnFindSelect is not an event handler itself. It is probably being called from another event handler (or more than 1). Try looking for all calls to it and see if that makes sense
I have two textboxes for entering the name and price of an item, a submit button under it, and a bulleted list under that that shows the current items.
On clicking the submit button the new item should be entered in the list of items and the bulleted list refreshed with the new items.
What happens though is that if I put the code that generates the bulleted list in OnInit then the list isn't refreshed on the first postback. If I put it in Page_Load then the list just duplicates itself on every postback. Where am I supposed to put it and what am i doing wrong?
Here is my code.
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
List<Product> Products = (List<Product>)Session["Products"];
foreach (Product p in Products)
{
ListItem productname = new ListItem();
productname.Text = p.name;
blProducts.Items.Add(productname);
}
}
Here is the code of the submit button:
protected void btnSubmit_Click(object sender, EventArgs e)
{
List<Product> Products = (List<Product>)Session["Products"];
string name = txtName.Text;
decimal price = decimal.Parse(txtPrice.Text);
Product p = new Product(name, price);
Products.Add(p);
Session["Products"] = Products;
}
The postback of the buttonclick happens AFTER init, so your order of events is:
Init adds 1 listitem for products
Button click happens, adding to products.
Since products is enumerated before the new item is added, it isn't reflected on your page.
Asp.Net Page Lifecycle Overview
you could move the init code to prerender, since that's the first event after handling postbacks. It may be doubling because you're never clearing that list of items, which, i believe, are stored in ViewState, so every time init gets called (every request), you are adding all of Products again. You could also wrap that section in an if(!Page.IsPostBack) and add directly to the list & the session in your button click, but it's probably better to fix the logic than duplicate the addition code.
Do
Page.IsPostBack == false.
Use:
page_load {
if(!Page.IsPostback)
CalltheLoadFunction
}
on_click {
_adds the stuff.
CalltheLoadFunction() //again
}
CalltheLoadFunction() {
dropdown.clear().
dropdown.datasource = datasource
dropddown.databind()
}
I wouldn't use Init. I use Page_load (ispostback false) in that function. After the button click, call the refresh data function again. You should check ispostback on the page load function all the time. Make sure it is false so that it doesn't load again.