how to fix this EventArgs c# - c#

I'm trying to build my own Simple Calculator.
I have this method with 10 references (from 0-10)
private void button_Click_1(object sender, EventArgs e)
{
Button b = (Button)sender;
tb.Text += b.ToString();
}`
Everything is working but the text sent to the TextBox come with extra things that I don't need.
I just want to show the number that I clicked on the calculator. I want to hide the "System.windows.forms.button, Text:" and show only the 7(in this case)

Use the Button.Text property of Button instead of ToString()
tb.Text += b.Text;

As Adil points out just use the Text property.
A further improvement can be made to your code base by instead of using the generated Event handler, create a single reusable event handler
instead of
private void button_Click_1(object sender, EventArgs e)
{
Button b = (Button)sender;
tb.Text += b.Text;
}
private void button_Click_2(object sender, EventArgs e)
{
Button b = (Button)sender;
tb.Text += b.Text;
}
private void button_Click_3(object sender, EventArgs e)
{
...
You could instead just have the single event handler. Remember to update your pointers on your buttons to point to this event handler.
private void numericButton_Click(object sender, EventArgs e)
{
Button b = (Button)sender;
tb.Text += b.Text;
}`

Related

How to get an attribute from an unspecified object?

My program dynamically creates a number of buttons at runtime. All of them get attached to an EventHandler, which links to the same method. How to know which button was pressed when the method executes? I tried using sender.Name, because object sender is a Button at runtime, but it doesn't compile.
List<Button> buttons = new List<Button>();
private void Form1_Load(object sender, EventArgs e)
{
for (int i = 1; i < 3; i++)
{
buttons.Add(new Button() { Name = "btn" + i });
buttons.Last().Click += new EventHandler(btn_Click);
}
}
public void btn_Click(object sender, EventArgs e)
{
MessageBox.Show(sender.Name + " is clicked");
}
You are on the right track.
The problem you have is that in btn_Click the sender is a generic object, so the compiler doesn't know what type it is, so you need to tell it by casting.
public void btn_Click(object sender, EventArgs e)
{
Button senderButton = (Button)sender;
MessageBox.Show(senderButton.Name + " is clicked");
}

How to create and call dynamically instantiated methods in C#? [duplicate]

I am creating one button on a page dynamically. Now I want to use the button click event on that button.
How can I do this in C# ASP.NET?
Button button = new Button();
button.Click += (s,e) => { your code; };
//button.Click += new EventHandler(button_Click);
container.Controls.Add(button);
//protected void button_Click (object sender, EventArgs e) { }
The easier one for newbies:
Button button = new Button();
button.Click += new EventHandler(button_Click);
protected void button_Click (object sender, EventArgs e)
{
Button button = sender as Button;
// identify which button was clicked and perform necessary actions
}
Simply add the eventhandler to the button when creating it.
button.Click += new EventHandler(this.button_Click);
void button_Click(object sender, System.EventArgs e)
{
//your stuff...
}
It is much easier to do:
Button button = new Button();
button.Click += delegate
{
// Your code
};
You can create button in a simple way, such as:
Button button = new Button();
button.Click += new EventHandler(button_Click);
protected void button_Click (object sender, EventArgs e)
{
Button button = sender as Button;
// identify which button was clicked and perform necessary actions
}
But event probably will not fire, because the element/elements must be recreated at every postback or you will lose the event handler.
I tried this solution that verify that ViewState is already Generated and recreate elements at every postback,
for example, imagine you create your button on an event click:
protected void Button_Click(object sender, EventArgs e)
{
if (Convert.ToString(ViewState["Generated"]) != "true")
{
CreateDynamicElements();
}
}
on postback, for example on page load, you should do this:
protected void Page_Load(object sender, EventArgs e)
{
if (Convert.ToString(ViewState["Generated"]) == "true") {
CreateDynamicElements();
}
}
In CreateDynamicElements() you can put all the elements you need, such as your button.
This worked very well for me.
public void CreateDynamicElements(){
Button button = new Button();
button.Click += new EventHandler(button_Click);
}
Let's say you have 25 objects and want one process to handle any one objects click event. You could write 25 delegates or use a loop to handle the click event.
public form1()
{
foreach (Panel pl in Container.Components)
{
pl.Click += Panel_Click;
}
}
private void Panel_Click(object sender, EventArgs e)
{
// Process the panel clicks here
int index = Panels.FindIndex(a => a == sender);
...
}

C# WinForm multiple click event handlers for similar function

I have a few toolStripMenuItems that act as a useful links for a series of websites, a rough example of the code would be something like:
private void toolStripMenuItem1_Click(object sender, EventArgs e)
{
Process.Start("http://www.google.com");
}
private void toolStripMenuItem2_Click(object sender, EventArgs e)
{
Process.Start("http://www.bing.com");
}
private void toolStripMenuItem3_Click(object sender, EventArgs e)
{
Process.Start("https://www.duckduckgo.com");
}
private void toolStripMenuItem4_Click(object sender, EventArgs e)
{
Process.Start("http://www.yahoo.com/");
}
...
Is there a more elegant way to handle this?
Put urls in menu items tag and attach this handler to all of them (hope it works)
private void toolStripMenuItemClick(object sender, EventArgs e)
{
Process.Start(sender.Tag.ToString());
}
The first thing to do is use the same handler for each one:
toolStripMenu1.Click += toolStripItemClick;
toolStripMenu2.Click += toolStripItemClick;
// etc
I would use the Tag property for this, set it when you're constructing the toolStripItems:
toolStripMenu1.Tag = "http://www.google.com";
And then define your handler:
private void toolStripItemClick(object sender, EventArgs e)
{
var c = (ToolStripMenuItem)sender;
Process.Start(c.Tag.ToString());
}
"Mash" all of the event handlers into one and then use the sender to see what ToolStripMenuItem was clicked.
private void toolStripMenuItem_Click(object sender, EventArgs e)
{
if(sender == toolStripMenuItem1)
Process.Start("http://www.google.com");
else if(sender == toolStripMenuItem2)
Process.Start("http://www.bing.com");
else if(sender == toolStripMenuItem3)
Process.Start("http://www.duckduckgo.com");
else if(sender == toolStripMenuItem4)
Process.Start("http://www.yahoo.com");
}
Or as Artem notes use the Tag member of the Control to store the String representing which site to visit. Then cast the sender.Tag to a String and use it.
toolStripMenuItem1.Tag = "http://www.google.com";
toolStripMenuItem2.Tag = "http://www.bing.com";
toolStripMenuItem3.Tag = "http://www.duckduckgo.com";
toolStripMenuItem4.Tag = "http://www.yahoo.com";
...
private void toolStripMenuItem_Click(object sender, EventArgs e)
{
Process.Start(sender.Tag.ToString());
}
You can also subscribe to click event using a lambda expression:
toolStripMenuItem1.Click += (_, __) => Process.Start("process1");
toolStripMenuItem2.Click += (_, __) => Process.Start("process2");

Combining Multiple Event Methods

Looking to refactor some application code. I have a GUI that has several of the same events that are reflected for different labels, textboxes, etc...
For example:
private void textBox1_Enter(object sender, EventArgs e)
{
textBox1.BackColor = Color.LightCyan;
}
and
private void textBox2_Enter(object sender, EventArgs e)
{
textBox2.BackColor = Color.LightCyan;
}
I just assign these methods to the event on the object properties in Visual Studio. Is there an efficient way to combine multiple event methods to clean up the code? Thanks!
Define a single event like:
private void textBox_Enter(object sender, EventArgs e)
{
TextBox textBox = sender as TextBox;
if (textBox != null)
textBox.BackColor = Color.LightCyan;
}
and then assign that event to all your TextBox Enter event like:
textBox1.Enter += textBox_Enter; //Same event handler
textBox2.Enter += textBox_Enter; //Same event handler
If both event handlers do the same exact logic, as you probably have listed here, just create 1 event handler and assign it to both components.
private void TextBox_Enter(object sender, EventArgs e)
{
TextBox textBox = sender as TextBox;
if (textBox != null) {
textBox.BackColor = Color.LightCyan;
}
}
To elaborate slightly you can take this approach even when you want to perform different actions depending on the control that fired the event.
private void textBox_Enter(object sender, EventArgs e)
{
//Check if the sender is textBox1
if(ReferenceEquals(sender, textBox1))
{
//Perform action on textBox1
}
//Check if the sender is textBox2
if(ReferenceEquals(sender, textBox2))
{
//Perform action on textBox2
}
}

how to create events on dynamic `textboxes`

I managed to create textboxes that are created at runtime on every button click. I want the text from textboxes to disappear when I click on them. I know how to create events, but not for dynamically created textboxes.
How would I wire this up to my new textboxes?
private void buttonClear_Text(object sender, EventArgs e)
{
myText.Text = "";
}
This is how you assign the event handler for every newly created textbox :
myTextbox.Click += new System.EventHandler(buttonClear_Text);
The sender parameter here should be the textbox which sent the even you will need to cast it to the correct control type and set the text as normal
if (sender is TextBox) {
((TextBox)sender).Text = "";
}
To register the event to the textbox
myText.Click += new System.EventHandler(buttonClear_Text);
Your question isn't very clear, but I suspect you just need to use the sender parameter:
private void buttonClear_Text(object sender, EventArgs e)
{
TextBox textBox = (TextBox) sender;
textBox.Text = "";
}
(The name of the method isn't particularly clear here, but as the question isn't either, I wasn't able to suggest a better one...)
when you create the textBoxObj:
RoutedEventHandler reh = new RoutedEventHandler(buttonClear_Text);
textBoxObj.Click += reh;
and I think (not 100% sure) you have to change the listener to
private void buttonClear_Text(object sender, RoutedEventArgs e)
{
...
}
I guess the OP wants to clear all the text from the created textBoxes
private void buttonClear_Text(object sender, EventArgs e)
{
ClearSpace(this);
}
public static void ClearSpace(Control control)
{
foreach (var c in control.Controls.OfType<TextBox>())
{
(c).Clear();
if (c.HasChildren)
ClearSpace(c);
}
}
This should do the job :
private void button2_Click(object sender, EventArgs e)
{
Button btn = new Button();
this.Controls.Add(btn);
// adtionally set the button location & position
//register the click handler
btn.Click += OnClickOfDynamicButton;
}
private void OnClickOfDynamicButton(object sender, EventArgs eventArgs)
{
//since you dont not need to know which of the created button is click, you just need the text to be ""
((Button) sender).Text = string.Empty;
}

Categories