I’m trying to dynamically declare an ImageButton.
I declare it and assign an ID and Image to it as follows:
ImageButton btn = new ImageButton();
btn.ImageUrl = "img/Delete.png";
btn.ID = oa1[i] + "_" + i;
btn.OnClick = "someMethod";
But when I try to assign an OnClick handler for the button it throws the following exception:
System.Web.UI.WebControls.ImageButton.OnClick is inaccessible due to protection level
You couldn't assign a value to a method like that, even if it were accessible. You need to subscribe to the event:
btn.Click += ClickHandlingMethod;
Take a look at this answer, it is related with dynamic controls and events
As Jon commented you cannot add a string to the event, in this case you need to add a handler for the event:
protected void Page_Init(object sender, EventArgs e)
{
var i = new ImageButton();
i.Click += new ImageClickEventHandler(i_Click);
this.myPanel.Controls.Add(i);
}
void i_Click(object sender, ImageClickEventArgs e)
{
// do something
}
Alternativeley
protected void Page_Init(object sender, EventArgs e)
{
var i = new ImageButton();
i.Click += (source, args) =>
{
// do something
};
this.myPanel.Controls.Add(i);
}
An example:
private void CreateAButton()
{
var button = new ImageButton();
button.ImageUrl = "yourimage.png";
button.ID = "Button1";
button.Click += ButtonClick;
Page.Form.Controls.Add(button);
}
private void ButtonClick(object sender, ImageClickEventArgs e)
{
// Do stuff here
// ...
}
You can use this code (one significant change) :
private void CreateAButton()
{
var button = new ImageButton();
button.ImageUrl = "yourimage.png";
button.ID = "Button1";
button.PostBackUrl = "http://www.towi.lt";
Page.Form.Controls.Add(button);
}
Trick is in "PostBackUrl". If you write correct link it will redirects to it (as in example). In other cases this will add original server name, '/' and text you entered. For example 'xxx' will be turned to "http://yourservername/xxx". It is very useful, when you working with redirects to same ISS, but different sites and dynamically creating buttons for users.
Related
I'm creating Buttons programmatically with a method and am wanting to attach a Click event handler. However, that data currently comes from a string parameter which can't be used with += RoutedEventHandler.
public Button CreateButton(string Display, string Name, string ClickEventHandler)
{
Button Btn = new Button
{
Content = Display,
Name = "Btn_" + Name
};
Btn.Click += new RoutedEventHandler(ClickEventHandler);
return Btn;
}
void Btn_save_Click(object sender, RoutedEventArgs e)
{
throw new NotImplementedException();
}
// later
Button MyButton = CreateButton("Save", "save", "Btn_save_Click");
Error is RoutedEventHandler expects a Method and not a String. Is there a different approach to programmatically binding events that allows this sort of behaviour?
Thanks
From what I understand you wish to pass the method that should be executed when Click event is triggered. You could do something along the lines of:
Button button = CreateButton("Save", "save", (s, e) => SomeOnClickEvent(s, e));
Button button2 = CreateButton("Create", "create", (s, e) => SomeOtherOnClickEvent(s, e));
public Button CreateButton(string display, string name, Action<object, EventArgs> click)
{
Button b = new Button()
{
Content = display,
Name = $"Btn_{name}"
};
b.Click += new EventHandler(click);
return b;
}
void SomeOnClickEvent(object sender, EventArgs e)
{
}
void SomeOtherOnClickEvent(object sender, EventArgs e)
{
}
I am not entirely sure what you are trying to accomplish with this.
Here is an example of how to create an event at run time.
public void CreateButton()
{
Button Btn = new Button();
Btn.Click += new EventHandler(btn_Clicked);
}
private void btn_Clicked(object sender, EventArgs e)
{
// Your Logic here
}
I want to create an imagebutton in code behind like this:
ImageButton img1 = new ImageButton();
img1.CssClass = "stylImage";
img1.ImageUrl = #"~/images/Workflow/esign.jpg";
img1.AlternateText = "Signature";
img1.CommandName = "edit";
img1.Click += new ImageClickEventHandler(Image_OnClientClick);
img1.Command += new CommandEventHandler(Image_OnCommand);
workdesk.Controls.Add(img1);
The button create and display on page, but none of the click or command event fire.
There is no error or exception too.
Any ideas?!?
Your code works fine and both the events fires perfectly as I tested.
There may be a chance that you have not specified the Event Definition correctly.
Please recheck the below code which works like a charme..!!
protected void Page_Load(object sender, EventArgs e)
{
ImageButton img1 = new ImageButton();
img1.CssClass = "stylImage";
img1.ImageUrl = #"~/images/Workflow/esign.jpg";
img1.AlternateText = "Signature";
img1.CommandName = "edit";
img1.Click += new ImageClickEventHandler(Image_OnClientClick);
img1.Command += new CommandEventHandler(Image_OnCommand);
form1.Controls.Add(img1);
}
protected void Image_OnClientClick(object sender, ImageClickEventArgs e)
{
//some code...
}
protected void Image_OnCommand(object sender, CommandEventArgs e)
{
//some code...
}
This may help you..!!
I came to the same question again and again. I need to use the user entered values after a button event, or a doubleclick, or anything. when I do it with the designer, it passes automatically the txt control and its value to the whole program, and I can use it anywhere. But programatically I couldn't solve it.
here's a little example:
private void Form1_Load(object sender, EventArgs e)
{
string blabla = "anything";
Button btn = new Button();
btn.Location = new Point(10, 40);
btn.Text = "Click me";
btn.Click += new EventHandler(btn_Click);
this.Controls.Add(btn);
}
void btn_Click(object sender, EventArgs e)
{
MessageBox.Show(blabla);
}
this doesn't work, so I added a "public" and the script goes:
public string blabla;
private void Form1_Load(object sender, EventArgs e)
{
blabla = "anything";
Button btn = new Button();
btn.Location = new Point(10, 40);
btn.Text = "Click me";
btn.Click += new EventHandler(btn_Click);
this.Controls.Add(btn);
}
void btn_Click(object sender, EventArgs e)
{
MessageBox.Show(blabla);
}
And so I can use my variable with the changed values. This goes well with controls too.
This works, but this makes thousands of public variables in a bigger application. How can I increase the readability by losing these publics? Is there a way to use "ref"? I saw it on the automatic "extract method", I just don't know, how can I use that with events.
Maybe I am on the wrong track in this, if there is a shortcut or other solution, please help.
The important change between the two snippets wasn't the fact that you made the variable public - it's that you changed it from a local variable in the Form1_Load method into an instance variable. It can still be a private instance variable, if you're handling it in the same class.
However, another alternative is to keep it as a local variable but use an anonymous function to handle the event:
private void Form1_Load(object sender, EventArgs e)
{
string blabla = "anything";
Button btn = new Button();
btn.Location = new Point(10, 40);
btn.Text = "Click me";
btn.Click += (sender, args) => {
MessageBox.Show(blabla);
// Other code here, but hopefully not too much...
};
this.Controls.Add(btn);
}
(As noted, you don't want to make the anonymous function too big, for the sake of readability - but it can always call another method with all the appropriate state.)
EDIT: As you're using VS2005, you're only using C# 2 so you can't use lambda expressions. You can use anonymous methods though. The code would then be:
private void Form1_Load(object sender, EventArgs e)
{
string blabla = "anything";
Button btn = new Button();
btn.Location = new Point(10, 40);
btn.Text = "Click me";
btn.Click += delegate {
MessageBox.Show(blabla);
// Other code here, but hopefully not too much...
};
this.Controls.Add(btn);
}
All winforms controls tend to have a Tag property, of type object which you can use to store your own custom data if you wish. Its not particularly good practice, and shows up some other architectural problems but here you go:
private void Form1_Load(object sender, EventArgs e)
{
Button btn = new Button();
btn.Location = new Point(10, 40);
btn.Text = "Click me";
btn.Click += new EventHandler(btn_Click);
btn.Tag = "blahblah";
this.Controls.Add(btn);
}
void btn_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
MessageBox.Show(btn.Tag.ToString());
}
You can do it with lambdas.
btn.Click += (sender, e) => { MessageBox.Show(blabla); }
You can do it my making a closure inside the Form1_Load method like this
private void Form1_Load(object sender, EventArgs e)
{
blabla = "anything";
Button btn = new Button();
btn.Location = new Point(10, 40);
btn.Text = "Click me";
btn.Click += (s,e) => MessageBox.Show(blabla);
this.Controls.Add(btn);
}
Even if blabla goes out of scope, the closure will still know that it contained the text "anything" when you click the button.
I add buttons dynamically.. e.g. Button newButton=new Button();
Now i want each button to be triggered. So i wrote them the following events:
public void response_Click(object sender, EventArgs e)
{
}
public void edit_Click(object sender, EventArgs e)
{
}
public void quote_Click(object sender, EventArgs e)
{
}
Button quote = new Button();
Button reply = new Button();
Button edit = new Button();
quote.ID = "quote";
reply.ID = "reply";
edit.ID = "edit";
How do i trigger them, as soon as the user clicks on the button..will my functions above be triggered? do i need to do the following:
this.Clicked+=quote;
this.Clicked+=reply;
this.Clicked+=edit;
if i do need to do that..where do i put those lines of code?
i use visual studio 1010. asp.net
You can do like..
quote.Click += new EventHandler(quote_Click);
reply.Click += new EventHandler(response_Click);
edit.Click += new EventHandler(edit_Click);
Yes, you would need to register the event of the button and associate it with particular method.
for example.
myButton.Click += new EventHandler(Button_Click);
void Button_Click(object sender, EventArgs e)
{
}
I have two controls created on Form_Load, a button and a combobox. I also have an event for the button, but the event should be able to see the newly created combobox.
When I try to call the combobox by it's name it says that it doesn't exist in this context.
private void Form1_Load(object sender, EventArgs e)
{
Button przycisk = new Button();
przycisk.Name = "przycisk";
przycisk.Dock = DockStyle.Bottom;
przycisk.Text = "Wybierz";
ComboBox kombo = new ComboBox();
kombo.Name = "kombo";
kombo.Dock = DockStyle.Bottom;
kombo.Items.Add("Przycisk");
kombo.Items.Add("Etykeita");
kombo.Items.Add("Pole tekstowe");
Controls.Add(kombo);
Controls.Add(przycisk);
przycisk.Click += new EventHandler(przycisk_Click);
}
private void przycisk_Click(object sender, EventArgs e)
{
kombo.Items.Add("Panel"); //just an example
}
Is there a way to make this work?
Only controls which are in used in markup with runat="server" will be class variables on your page. They are actually defined in the designer file.
What you'll want to do is in the class add something like the following where you have a class variable, then assign kombo in your page-load function. Then, it will exist in your click event handler.
// kombo is now scoped for use throughout this class
ComboBox kombo = null;
private void Form1_Load(object sender, EventArgs e)
{
Button przycisk = new Button();
przycisk.Name = "przycisk";
przycisk.Dock = DockStyle.Bottom;
przycisk.Text = "Wybierz";
// Assign to our kombo instance
kombo = new ComboBox();
kombo.Name = "kombo";
kombo.Dock = DockStyle.Bottom;
kombo.Items.Add("Przycisk");
kombo.Items.Add("Etykeita");
kombo.Items.Add("Pole tekstowe");
Controls.Add(kombo);
Controls.Add(przycisk);
przycisk.Click += new EventHandler(przycisk_Click);
}
private void przycisk_Click(object sender, EventArgs e)
{
// Using the kombo we created in form load, which is still referenced
// in the class
kombo.Items.Add("Panel"); //just an example
}
You will have to use the FindControl() method to find the object first.
private void przycisk_Click(object sender, EventArgs e)
{
ComboBox kombo = (ComboBox)FindControl("kombo");
kombo.Items.Add("Panel");
}