I need to generate a dynamic list of buttons, I already did, with an event handler attached to it.
However the event handler is not being executed.
private void GetOptions(EcoBonusRequest request)
{
var ecobonuswworkflow = WorkflowFactory.CreateEcobonusWorkflow();
ecobonuswworkflow.SetCurrentStep(request.CurrentStatus);
var currentoptions = ecobonuswworkflow.GetCurrentOptions();
foreach(var option in currentoptions)
{
var btn = new Button() {Text = option.OptionName};
btn.Click +=new EventHandler(btn_Click);
Buttons.Controls.Add(btn);
}
}
void btn_Click(object sender, EventArgs e)
{
var btn = (Button) sender;
string command = btn.Text;
EcoBonusRequest request = this.GetDBRequest(RequestBaseId.Value);
EcoBonusRequestBL.AddWorkflowHistoryItem(request, command,CurrentUser, command);
}
The controls that you add dynamically in your page must be added in Page_init event, and they must have unique Ids. If you are adding textboxes or some other controls where user can input or change value, than on every post back when these controls are re-added they must have same IDs.
Related
I am working on C# windows application. my application get controls(button,text box,rich text box and combo box etc)from custom control library and placed them into form dynamically at run time. how i create event handler for that controls using delegate? and how to add business logic in particular custom control click event?
For Example:
i have user1, user2, user3, when user1 log in i want to show only "save" button. when user2 then only show "add and delete" buttons and user 3 only show "add and update" buttons.text boxes and button created as per user log in information taken from DB tables.in this scenario how i handle different event(adding,saving,updating,deleting) for button save,add,delete and update for different users when form is dynamically created controls(save,add,delete and update button object is from same button class)
With anonymous method:
Button button1 = new Button();
button1.Click += delegate
{
// Do something
};
With an anonymous method with explicit parameters:
Button button1 = new Button();
button1.Click += delegate (object sender, EventArgs e)
{
// Do something
};
With lambda syntax for an anonymous method:
Button button1 = new Button();
button1.Click += (object sender, EventArgs e) =>
{
// Do something
};
With method:
Button button1 = new Button();
button1.Click += button1_Click;
private void button1_Click(object sender, EventArgs e)
{
// Do something
}
Further information you can find in the MSDN Documentation.
var t = new TextBox();
t.MouseDoubleClick+=new System.Windows.Input.MouseButtonEventHandler(t_MouseDoubleClick);
private void t_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
throw new NotImplementedException();
}
It's adding double click eventhandler to new TextBox
I believe you could do something like this:
if (userCanAdd)
container.Controls.Add(GetAddButton());
if (userCanUpdate)
container.Controls.Add(GetUpdateButton());
if (userCanDelete)
container.Controls.Add(GetDeleteButton());
private Button GetAddButton() {
var addButton = new Button();
// init properties here
addButton.Click += (s,e) => { /* add logic here */ };
// addButton.Click += (s,e) => Add();
// addButton.Click += OnAddButtonClick;
return addButton;
}
private void OnAddButtonClick (object sender, EventArgs e) {
// add logic here
}
// The other methods are similar to the GetAddButton method.
I am developing a custom control which renders (a) textbox(es), in its textchange event I want to asynchronously send the value to the control where it would search and make the data available in an exposed property to be fetched later on page load. But my problem is, HOW TO ASYNCHRONOUSLY CALL A METHOD CODED INSIDE MY CONTROL to do the search functionality. For now, the textbox textchange and the buttons click events are not firing, the button click loads the page and writing in the textbox does nothing. Here is the code.
public int Count { get; set; }
public List<object> Selection { get; set; }
public object SelectedObject { get; set; }
public Label label;
public TextBox textBox;
protected override void RenderContents(HtmlTextWriter output)
{
textBox = new TextBox();
textBox.TextChanged += new EventHandler(Method);
UpdatePanel up = new UpdatePanel();
up.ID = "UpdatePanel1";
up.ChildrenAsTriggers = true;
up.UpdateMode = UpdatePanelUpdateMode.Conditional;
up.ContentTemplateContainer.Controls.Add(a);
this.label = new Label();
this.label.Text = "Initialized Text.";
up.ContentTemplateContainer.Controls.Add(this.label);
Button button = new Button();
button.Text = "Say Hello";
button.Click += new EventHandler(HandleButtonClick);
up.ContentTemplateContainer.Controls.Add(button);
this.Controls.Add(up);
foreach (Control c in this.Controls)
{
c.RenderControl(output);
}
}
private List<object> Get(string searchValue)
{
throw new NotImplementedException();
}
public void Method(object sender, EventArgs e) {
(sender as TextBox).Text += " ";
//Selection = Get((sender as TextBox).Text);
}
private void HandleButtonClick(object sender, EventArgs e)
{
this.label.Text = "Hello " + this.textBox.Text;
//Selection = Get(this.textBox.Text);
}
found out the you have to inherit your control from IPostBackDataHandler, also, the asynchronous problem is there. I have used a workaround, I have put the control in updatepanel (put updatepanel on aspx), registered a button through control onclick of which is bound, on jquery/javascript I am firing the click event of the button to send the calls asynchronously. Things work fine, but after firing that event javascript code doesnt run again, tried calling the function by registering client script in prerender again, didnt work.
Currently, I am doing a project for students' hostel and now I have to implement some search strategies about students.Here I have to create a button dynamically when the user clicks on the another server button in .aspx page and accordingly I have to create the onclick event handler for the newly created button. The code-snippet that I used is:
protected void btnsearchByName_Click(object sender, EventArgs e)
{
TextBox tbsearchByName = new TextBox();
Button btnsearchName = new Button();
tbsearchByName.Width = 250;
tbsearchByName.ID = "tbsearchByName";
tbsearchByName.Text = "Enter the full name of a student";
btnsearchName.ID = "btnsearchName";
btnsearchName.Text = "Search";
btnsearchName.Click += new EventHandler(this.btnsearchName_Click);
pnlsearchStudents.Controls.Add(tbsearchByName);
pnlsearchStudents.Controls.Add(btnsearchName);
}
protected void btnsearchName_Click(object sender, EventArgs e)
{
lblsearch.Text = "btnsearchName_Click event fired in " + DateTime.Now.ToString();
}
Here, the problem is newly created eventHandler doesnot get fired. I have gone through this site and looked several questions and answers and also gone through the page life-cycle and they all say that the dynamic button should be on Init or Pre_init, but my problem is I have to create it when another button is clicked, how can it be possible?
You need to add the click handler for the button on every postback.
you could look for the button in the search students panel on page load or try the page OnInit() method to add the handler when its created.
Also check here:
Dynamically added ASP.NET button click handler being ignored
and here:
asp.net dynamically button with event handler
and here:
asp:Button Click event not being fired
(all of which give similar suggestions)
Try this http://msdn.microsoft.com/ru-ru/library/system.web.ui.webcontrols.button.command(v=vs.90).aspx
btnsearchName.Command += new CommandEventHandler(this.btnsearchName_Click);
btnsearchName.CommandName = "Click";
You need to recreate the button and attach the event handler every time. For this, create a list of button and save it on session. On page load, go through the List and create the button every time
public Button create_button()
{
btnsearchName.ID = "btnsearchName";
btnsearchName.Text = "Search";
btnsearchName.Click += new EventHandler(this.btnsearchName_Click);
return btnsearchName;
}
public TextBox create_textbox()
{
TextBox tbsearchByName = new TextBox();
Button btnsearchName = new Button();
tbsearchByName.Width = 250;
tbsearchByName.ID = "tbsearchByName";
tbsearchByName.Text = "Enter the full name of a student";
return tbsearchByName;
}
protected void btnsearchByName_Click(object sender, EventArgs e)
{
TextBox tbsearchByName = create_textbox();
Button btnsearchName = create_button();
//add to panels
pnlsearchStudents.Controls.Add(tbsearchByName);
pnlsearchStudents.Controls.Add(btnsearchName);
//add to session
List<Button> lstbutton = Session["btn"] as List<Button>
lstbutton.add(btnsearchName);
//similarly add textbox
//again add to session
Session["btn"] = lstbutton
}
public override page_load(object sender, eventargs e)
{
//fetch from session, the lstButton and TextBox and recreate them
List<Button> lstbutton = Session["btn"] as List<Button>;
foreach(Button b in lstbutton)
pnlsearchStudents.Controls.Add(b);
//similar for textbox
}
I am not sure but may be you have to override the OnInit() method like this.
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
}
You just need to add this code on ready state of jquery code and it will work fine for the dynamic button too
$(document).ready(function(){
$('input#tbsearchByName').click(function(){
// code goes here
});
});
I am using the following code to add buttons to a list:
for (int i=0; i < mov.Theat.Count(); i++)
{
StackPanel st=new StackPanel();
st.Orientation=System.Windows.Controls.Orientation.Horizontal;
st.HorizontalAlignment = HorizontalAlignment.Center;
TextBlock tx = new TextBlock();
tx.Text=mov.Theat[i];
st.Children.Add(tx);
TextBlock tx2=new TextBlock();
tx2.Text=mov.Time[i];
st.Children.Add(tx2);
Button test = new Button();
test.Width=450;
test.Content = st;
test.Click += new RoutedEventHandler(Button_Click);
theatlist.Items.Add(test);
}
As for the event handler, it is shown below:
void Button_Click(object sender, RoutedEventArgs e)
{
Theat_Data TD=(App.Current as App).Theat.First(theat => theat.Name=="");
PhoneApplicationService.Current.State["Theat"] = TD;
this.GoToPage(ApplicationPages.Theat);
}
I want to pass some variable about the selected button in the even handler so how can this be done? And if this is not possible, then what options do I have to identify the button and pass some data about it to the event handler?
I assume your business object is called Thead_Data and you would like to have access to this object from within your Click-method:
During creation, attach your data object to the DataContext or the Tag property:
Button test = new Button(){DataContext=Theat[i]};
Within your event handler, cast the DataContext or the Tag-property to your business-object:
void Button_Click(object sender, RoutedEventArgs e){
Button btn=(Button)sender;
Theat_Data td=(Theat_Data)button.DataContext;
...
}
You can access the sender like this:
void Button_Click(object sender, RoutedEventArgs e)
{
var clickedButton = sender as Button;
}
I'm not sure I completely understand what you are asking, but the "sender" param of the event handler is the button. You should just be able to cast it:
Button b = (Button)sender;
You could write your own event handler and add your custom data in the event args.
I am creating 7 buttons on the fly
when i create the buttons i am trying to have an event handler than can deal with all clicks in one method via a switch. Ideally i want to pass an id with the button that indicates what was clicked, opposed to this solution of
void pdfButton_Click(object sender, EventArgs e)
{
Button b = (Button)sender;
Console.WriteLine(b.Text);
}
as all of the buttons using this event handler have the same text. I have a unique id associated witht the buttons but no idea how to send them
thanks
You can use the Name or Tag properties.
Put the ID in the Tag property on the button when you create them and then check the ID in your event handler.
Button button = new Button();
button.Tag = 1;
...
void pdfButton_Click(object sender, EventArgs e)
{
Button b = (Button)sender;
switch ((int)b.Tag)
{
...
}
}
First: Bad practice to handle several clicks in one event via switch. But however a solution would be:
Create your own control which inherits the button and ad your ID as an property. So you can access it via:
MyButton b = (MyButton)sender;
switch(b.ID) {
//Code goes here
}
If each button you add has a unique Id, why not just use the ID property of the button?
Button button = new Button();
button.ID= "Button1";
//...
void pdfButton_Click(object sender, EventArgs e)
{
Button b = (Button)sender;
switch(button.ID)
{
case "Button1":
//...
}
}