How to get an attribute from an unspecified object? - c#

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");
}

Related

how to fix this EventArgs 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;
}`

Creating unique event handlers for dynamically created buttons

I want to add buttons to my page dynamically. It will depend on the number of results from a SELECT statement. I
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
for (int i = 0; i < Query.length; i++)
{
Button btn = new Button();
btn.ID = "Button" + i;
btn.Click += new EventHandler(btn_Click());
btn.Text = i.ToString();
pagingPanel.Controls.Add(btn);
}
}
}
But I want each button to have it's own custom event handler. If I click one button, I want it do have a different result than if I click another. I would like to do something like this where I can pass an aditional parameter:
protected void btn_Click(object sender, EventArgs e, string test)
{
System.Diagnostics.Debug.WriteLine(test);
}
Perhaps I don't know which objects to pass? Or maybe I am approaching this the wrong way.
How do I achieve the desired results?
Try this:
protected void Page_Load(object sender, EventArgs e)
{
// you do not use !IsPostBack here
//count of func must be equal with 'Query.Length'
string[,] arr ={
{"func1","hello world"},
{"func2","Hello ASP.NET"}
};
for (int i = 0; i < Query.Length; i++)//I assume length is 2
{
Button btn = new Button();
btn.ID = arr[i, 0];
btn.CommandArgument = arr[i, 1];
btn.Click += new EventHandler(btn_Click);
btn.Text = i.ToString();
pagingPanel.Controls.Add(btn);
}
}
protected void btn_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
System.Reflection.MethodInfo methodInfo = typeof(_Default2).GetMethod(btn.ID); //_Default2 is class name of code behind
if (methodInfo != null)
{
object[] parameters = new object[] { btn.CommandArgument};
methodInfo.Invoke(this,parameters);
}
}
public void func1(object args)
{
string test = args.ToString();
Response.Write(test);
}
public void func2(object args)
{
string test = args.ToString();
Response.Write(test);
}
First and foremost - you have to create buttons whether it is postback or not. The button click is the reason for the postback, if you don't have buttons - what will be clicking?
Second, add to your page class:
Dictionary<Button, ButtonInfo> fButtonLookup = new Dictionary<Button, ButtonInfo>();
Then, where you create buttons:
fButtonLookup.Clear();
for (int i = 0; i < Query.length; i++)
{
Button btn = new Button();
fButtonLookup.Add(btn, new ButtonInfo() { whatever information about this button you want to keep});
...
}
Then, in your button click:
protected void btn_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
if (fButtonLookup.ContainsKey(btn))
{
ButtonInfo info = fButtonLookup[btn];
// do waht you need with button information
}
}
You could just check sender to see which button was clicked:
protected void btn_Click(object sender, EventArgs e)
{
if (sender == btnOne)
performBtnOne("foo");
else if (sender == btnTwo)
performButtonTwo("bar");
}
To expand on itsme86...
protected void btn_Click(object sender, EventArgs e)
{
Button btn = (Button)sender; //Now you have an instantiated version of the button pressed.
switch (btn.Name)
{
case "foo":
performBtnOne();
break;
case "bar":
performBtnTwo();
break;
default:
performUnexpectedButton();
break;
}
}

How to Use Dynamically Created Button/textBox in C# Windows Forms?

private void createButton()
{
flowLayoutPanel1.Controls.Clear();
for (int i = 0; i < 4; i++)
{
Button b = new Button();
b.Name = i.ToString();
b.Text = "Button" + i.ToString();
flowLayoutPanel1.Controls.Add(b);
}
}
private void button1_Click(object sender, EventArgs e)
{
createButton();
}
I Used this code to create some buttons on runtime , now how can i use those created buttons to perform diffrent actions? Im kindz new to this so please help me , very much appreciated :)
You can assign an event handler to the click event:
b.Click += SomeMethod;
SomeMethod must have the following signature:
void SomeMethod(object sender, EventArgs e)
b.Click += delegate(object sender, EventArgs e) {
Button clickedButton = (Button)sender; //gets the clicked button
});
When you create your button, you need to subscribe to the Click event like this :
Button b = new Button();
b.Click += new EventHandler(b_Click);
// or
b.Click += b_Click;
// or
b.Click += delegate(object sender, EventArgs e) {/* any action */});
// or
b.Click += (s, e) => { /* any action */ };
void b_Click(object sender, EventArgs e)
{
// any action
}
This is something that is automatically done when your are is the designer in Visual Studio, and you click on a button to create the method button1_Click.
You can search in the Designer.cs of your form, you will find an equivalent line:
button1.Click += new EventHandler(button1_Click);
Related question:
How can i create dynamic button click event on dynamic button

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;
}

How do I identify which control generated the Click event?

In the following code, how do I identify which control raised the Click event?
void x_Click(object sender, EventArgs e)
{
//How do I identify the sender?
}
private void fill()
{
for(blah)
{
Button x = new Button();
x.Click += new EventHandler(x_Click);
this.controls.Add(x)
}
}
void x_Click(object sender, EventArgs e)
{
Button who = (Button) sender;
// you can now access who.Text, etc.
}

Categories