I dynamically created a Form and inside I created a button, but when I try to add my function to the button it gives this error:
Method name expected.
I am using the following code:
{
...
Form newForm = new Form();
newform.Size = new Size(477, 222);
Button btn = new Button();
btn.Size = new Size(121, 23);
btn.Location = new Point(231, 102);
btn.Text = "Text";
btn.Click += new EventHandler(Funct(label1.Text, label12.Text));
newForm.Controls.Add(btn);
}
public void Funct(string stringA, string stringB)
{
StreamWriter write = new StreamWriter(path);
write.WriteLine(stringA + "-" + stringB);
write.Close();
}
What can I do to resolve this issue?
The problem is the Funct does not comply with the signature for the Click event:
Try:
public void Funct(object sender, EventArgs e)
{
...
}
If you want to dynamically pass the strings, you may have to create your own EventArgs class adding the additional properties there.
Hope that helps.
Use lambda, change click event to
btn.Click += (s, e) => { Funct(label1.Text, label12.Text) };
Related
In the Form1_Load method what code should I write to create a simple button?
private void Form1_Load(object sender, System.EventArgs e)
{
}
So that on Load the button would show.
As you said it is Winforms, you can do the following...
First create a new Button object.
Button newButton = new Button();
Then add it to the form inside that function using:
this.Controls.Add(newButton);
Extra properties you can set...
newButton.Text = "Created Button";
newButton.Location = new Point(70,70);
newButton.Size = new Size(50, 100);
Your issue you're running to is that you're trying to set it on Form_Load event, at that stage the form does not exist yet and your buttons are overwritten. You need a delegate for the Shown or Activated events in order to show the button.
For example inside your Form1 constructor,
public Form1()
{
InitializeComponent();
this.Shown += CreateButtonDelegate;
}
Your actual delegate is where you create your button and add it to the form, something like this will work.
private void CreateButtonDelegate(object sender, EventArgs e)
{
Button newButton= new Button();
this.Controls.Add(newButton);
newButton.Text = "Created Button";
newButton.Location = new Point(70,70);
newButton.Size = new Size(50, 100);
newButton.Location = new Point(20, 50);
}
on your eventload form put this code
private void Form1_Load(object sender, EventArgs e)
{
Button testbutton = new Button();
testbutton.Text = "button1";
testbutton.Location = new Point(70, 70);
testbutton.Size = new Size(100, 100);
testbutton.Visible = true;
testbutton.BringToFront();
this.Controls.Add(testbutton);
}
It's simple :
private void Form1_Load(object sender, System.EventArgs e)
{
Button btn1 = new Button();
this.Controls.add(btn1);
btn1.Top=100;
btn1.Left=100;
btn1.Text="My Button";
}
I am using Tabcontrol and I created a class for all new Tabpages.
For examle when I open a new Tabpage the class creates controls and places them.
bttn1 = new Button();
bttn1.Name = "button1";
bttn1.Text = "Start";
bttn1.Location = new Point(3, 405);
bttn1.Size = new Size(75, 23);
tp.Controls.Add(bttn1);
So my question is how can I check if this button is clicked?
Also my other question is the same with a Timer tick event.
You can easily attach to the button's Click event from the code:
bttn1.Click += new EventHandler(butt1_Click);
And here's the handler:
void button1_Click(object sender, EventArgs e)
{
// ...
}
Visual Studio will help you when you type the Click +=. After typing +=, hit the Tab key twice to get the handler.
I hope that you have created a UserControl for this or have sub-classed the TabPage class to create your controls. You should expose the Click event of the button from this newly created class through some new event you create:
public class MyTabPage : TabPage
{
private Button bttn1;
public event EventHandler Button1Clicked;
public MyTabPage()
{
bttn1 = new Button();
bttn1.Name = "button1";
bttn1.Text = "Start";
bttn1.Location = new Point(3, 405);
bttn1.Size = new Size(75, 23);
bttn1.Click += bttn1_Click;
this.Controls.Add(bttn1);
}
void bttn1_Click(object sender, EventArgs e)
{
OnButton1Clicked();
}
protected virtual void OnButton1Clicked()
{
var h = Button1Clicked;
if (h != null)
h(this, EventArgs.Empty);
}
}
Now when you create an instance of MyTabPage, you can attach a handler to the Button1Clicked event:
MyTabPage page = new MyTabPage();
page.Button1Clicked += page_Button1Clicked;
tabControl.TabPages.Add(page);
...
void page_Button1Clicked(object sender, EventArgs e)
{
}
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.
Actually, I want to know how to add it's click event.
Button b = new Button();
b.Text = "Go back!";
b.ID = "btn_Back";
b.Click = ??
b.Click += new EventHandler(btn_Click);
and then declare btn_Click, like:
void btn_Click(object sender, EventArgs e)
{
throw new NotImplementedException();
}
If you're in VS2005 versions, once you hit b.Click += you'll be queried to hit TAB and declare it all automatically!
Kind regards,
Henrik.
Here is how to register the event handler (using the += notation):
b.Click += new EventHandler(NameOfHandler);
You will need a function called NameOfHandler that corresponds to the EventHandler delegate - that is, that takes a first parameter of type object and a second paremeter of type EventArgs:
public void NameOfHandler(object o, EventArgs e)
{
// code here
}
Normally, in visual studio once you have typed the += following the event name, tabbing a couple of times will generate the rest of the line and an empty event handler function.
Button b = new Button();
b.Text = "Go back!";
b.ID = "btn_Back";
b.Click += new EventHandler(B_Click);
Controls.Add(b);
// ...
private void B_Click(object sender, EventArgs e)
{
// ...
}
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.