Indirect reference to a button - c#

I'm having this code:
private void b9_Click(object sender, EventArgs e)
{
b9.Enabled = false;
color = 8;
}
The problem is that i'm having a lot of buttons for disabling. Is there a chance i can use something like:
this.Enabled=false;

Probably that is what you want
private void OnClick(object sender, EventArgs e)
{
if( sender is Button )
{
Button button = (Button)sender;
button.Enabled = false;
}
}
Use this routine for every button you need to disable on click.

It is known as single event handler for multiple controls. Just put following event handler for your buttons as many as you like.
public void Button_Click(object sender, EventArgs e)
{
Button button = (Button)sender;
button.IsEnable = false;
// If you want to access text in the button
... = button.Content as object;
}

private void OnClick(object sender, EventArgs e)
{
Button btn = sender as Button; // if sender is not a Button, btn will be null
if (btn != null)
{
btn.Enabled = false;
}
}
If you want to apply the same behaviour to any clickable control, you can use Control class instead of Button. Button inherits from Control and the property Enabled is defined in Control class.
private void OnClick(object sender, EventArgs e)
{
Control ctrl = sender as Control; // if sender is not a Control, ctrl will be null
if (ctrl != null)
{
ctrl .Enabled = false;
}
}
Also, if you want to go one step further, you can create a method that disables the clicked control. Something like this:
private void DisableControl(object sender)
{
Control ctrl = sender as Control;
if (ctrl != null)
{
ctrl.Enabled = false;
}
}
Then, you can call this method from the Click even handler like this:
private void OnClick(object sender, EventArgs e)
{
DisableControl(sender);
}

Related

I got a multiple buttons event handler here But I need to target only one button if it was clicked how do I do that?

private void btnCodeAkas_Click(object sender, EventArgs e)
{
tmrTimerAkas.Start();
tmrTimerTwoAkas.Start();
}
But I need to target only one button if it was clicked how do I do that?
well you can cast your sender to Control object so you can get the name of the button then you write your conditional logic.
private void button1_Click(object sender, EventArgs e)
{
var control = sender as Control;
if (control.Name == "button1")
{
Console.WriteLine($"Clicked {control.Name} button");
}
else if (((Control)sender).Name == "button2")
{
Console.WriteLine($"Clicked {control.Name} button");
}
}

How to pass button object to function

I have several buttons to click, and all the same function (that I want to create), they just differ by controller's name. For example:
private void markX()
{
buttonName.Text = "X";
buttonName.ForeColor = System.Drawing.Color.Red;
}
How can I pass the button object that that is modified in the function into the function's parameters?
Make it a Click event handler, attach it to each button, and use the sender parameter as the button to change.
void button_Click(Object sender, EventArgs e)
{
var button = sender as Button;
if(button != null)
{
button.Text = "X";
button.ForeColor = System.Drawing.Color.Red;
}
}
You don't need to pass the name of the button, you just need to pass an object of type button as an argument to your method.
private void markX(Button b)
{
b.Text = "Text";
b.Foreground = System.Drawing.Color.Red;
}
Use "sender":
private void Button_click(object sender, EventArgs e)
{
((Button)sender).Text = "X";
}
sender holds instance of event caller.
The click handler for the button click event has the following objects.
Object sender
EventArgs e
This will give you the name of the Button that was clicked, and just pass that to your function.
((Button)sender).Tag
Here is some sample code
private void Button_Clicked(Object sender, EventArgs e)
{
string name = ((Button)sender).Tag;
markX(name);
}

ButtonClick to get an Object on SelectionChanged event

I have a SelectionChanged event and works perfectly, but I want to figure out how to "catch" this selected item at the click of a button they need to pass it as parameter to another page and edit this Item. Here's the current code and button SelectionChanged I still implemented because this is what I need.
private void listCarros_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
ListBox listBox = sender as ListBox;
if (listBox != null && listBox.SelectedItem != null)
{
//pega o Carro que foi selecionado
Carro sCar = (Carro)listBox.SelectedItem;
btnEditCar.IsEnabled = true;
btnDeleteCar.IsEnabled = true;
}
else
{
btnEditCar.IsEnabled = false;
btnDeleteCar.IsEnabled = false;
}
}
I need to edit the selectedItem on this button:
private void btnEditCar_Click(object sender, EventArgs e)
{
//Here I need access to the selectedItem on SelectionChanged event.
}
If you could also tell me how to pass the object as parameter would be perfect.
You can do this with binding also
1.Bind ListBoxItem(Carro Object) to the tag of "btnEditCar" in xaml.
Xaml should be like this
<Button Name="btnEditCar" OnClick="btnEditCar_Click" Tag="{Binding}"/>
and now in
private void btnEditCar_Click(object sender, EventArgs e)
{
Carro sCar=(Carro)((sender as FrameworkElement).Tag)
}
This is the good practice,creating a class variable only for temporary purpose is hack
To give a better idea on my comments. Creating a class level variable is like this:
Notice that sCar is declared outside the method, but within the class.
Carro sCar = new Carro();
private void listCarros_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
ListBox listBox = sender as ListBox;
if (listBox != null && listBox.SelectedItem != null)
{
sCar = (Carro)listBox.SelectedItem;
...
private void btnEditCar_Click(object sender, EventArgs e)
{
sCar.ProperyYouWantToChange = "Stuff I want to change"
}

Changing the BackColor of a textbox upon entry

I have the following code for my form:
private void txt1_Enter(object sender, EventArgs e)
{
txt1.SelectAll();
txt1.BackColor = Color.LightBlue;
}
private void txt2_Enter(object sender, EventArgs e)
{
txt2.SelectAll();
txt2.BackColor = Color.LightBlue;
}
private void txt1_Leave(object sender, EventArgs e)
{
txtThermalConductivity.BackColor = Color.White;
}
private void txt2_Leave(object sender, EventArgs e)
{
txtThermalConductivity.BackColor = Color.White;
}
There are another 20 textboxes on my form that I would like to do the same for. Is it possible to combine all of the enter events and all of the leave events so I have two events in total rather than 44 individual events?
In your Designer view, select each textbox and set the Enter and Leave events to point to a single implementation of each.
Then you can do this:
private void txt_enter(object sender, EventArgs e) {
((TextBox)sender).BackColor = Color.LightBlue;
}
private void txt_leave(object sender, EventArgs e) {
((TextBox)sender).BackColor = Color.White;
}
Also, SelectAll isn't required because you're setting the entire textbox's background color.. not the SelectionColor of a RichTextBox.
You could either add manually or iterate over all textboxes in form (extension method found here GetChildControls.
foreach (TextBox textBox in this.GetChildControls<TextBox>())
{
textBox.Enter += new EventHandler(TextBox_Enter);
textBox.Leave += new EventHandler(TextBox_Leave);
}
The above can be called from the Form's Load event.
The event listener now can look like the following by casting the sender to TextBox.
private void TextBox_Enter(object sender, EventArgs e)
{
TextBox txtBox = (TextBox)sender;
txtBox .SelectAll();
txtBox .BackColor = Color.LightBlue;
}
private void TextBox_Leave(object sender, EventArgs e)
{
TextBox txtBox = (TextBox)sender;
txtBox.BackColor = Color.White;
}
It is, just use something like the following:
private void tbLeave(object sender, EventArgs e) {
((TextBox) sender).BackColor = Color.White;
}
The set the controls event declaration to point to this function.
You can also do the same for the Leave() event.
(Just a little note to say, I much prefer to handle this kind of thing client side where possible.)

How can I refactor this C# code below?

I have 12 buttons in my Form1, and each button has a textbox next to it. The button event calls a method called dialogueOpen which handles getting the an object from form2 and placing a string value in a textbox.
How can I place the value returned in a textbox depending on what button the user clicked on? So if it is button1 a user clicked on, then the text returned should be placed in textbox1 and if it is button2 the user clicked on then the text returned should be placed in textbox2. The point is avoid using a string name to check as the buttons can all be called "browse".
Right now my code below does that but it is quite repetitive is there is a better of doing this?
private void dailogueOpen(String btnName)
{
if (listBox1.SelectedItem == null)
{
MessageBox.Show("Please Select a form");
}
else
{
var selectedItem = (FormItems)listBox1.SelectedItem;
var form2result = new Form2(myDataSet, selectedItem);
var resulOfForm2 = form2result.ShowDialog();
if (resulOfForm2 == DialogResult.OK)
{
switch (btnName)
{
case "btn1":
textBox1.Text = form2result.getValue();
break;
case "btn2":
textBox2.Text = form2result.getValue();
break;
case "btn3":
textBox3.Text = form2result.getValue();
break;
case "btn4":
textBox4.Text = form2result.getValue();
break;
case "btn5":
textBox5.Text = form2result.getValue();
break;
}
}
}
}
private void button1_Click(object sender, EventArgs e)
{
String name = "btn1";
dailogueOpen(name);
}
private void button2_Click(object sender, EventArgs e)
{
String name = "btn2";
dailogueOpen(name);
}
private void button3_Click(object sender, EventArgs e)
{
String name = "btn3";
dailogueOpen(name);
}
private void button4_Click(object sender, EventArgs e)
{
String name = "btn4";
dailogueOpen(name);
}
private void button5_Click(object sender, EventArgs e)
{
String name = "btn5";
dailogueOpen(name);
}
EDIT: I just noticed your event handlers. More refactoring ensues:
Yes, there is. You need to somehow associate textboxes to buttons. For example, create a dictionary like so:
Dictionary<Button, TextBox> _dict;
_dict[button1] = textBox1;
_dict[button2] = textBox2;
...
Use one event handler for all events:
private void button_click(object sender, EventArgs e)
{
dialogeOpen((Button)sender);
}
Change dialogueOpen to accept a Button instead of a string and
_dict[btn].Text = form2Result.getValue();
replace your eventhandlers to
private void ButtonClick(object sender, EventArgs e)
{
var button = sender as Button;
if (button == null) return;
String name = button.Text;// Tag, name etc
dailogueOpen(name);
}
1 You use the same delegate on all button
Nota (Thank's to Marty) : When You're in the Form Designer, select all buttons, and then assing then "Generic_Click" for all of them, or you can use code below.
this.btn1.Click += new System.EventHandler(Generic_Click); //the same delegate
this.btn2.Click += new System.EventHandler(Generic_Click);
this.btn3.Click += new System.EventHandler(Generic_Click);
....
private void Generic_Click(object sender, EventArgs e)
{
var control = (Button)sender;
if( control.Name == "btn1")
{
....
}
else if( control.Name == "btn2")
{
....
}
else if( control.Name == "btn3")
{
....
}
}
I would first use just one event handler for the buttons, it would look like this:
protected void ButtonClick(object sender, EventArgs e)
{
Button clickedButton = (Button) sender;
string selectedId = clickedButton.ID;
string[] idParameters = selectedId.Split('_');
string textBoxId = "textbox" + idParameters[1];
dailogueOpen(textBoxId);
}
What I did here is use a pattern for the names of the textboxes, so for instance if you have buttons with ids like: button_1 ,button_2, ..., button_n, you can infer what the corresponding textbox is.
If you click button_1, by spliting its id you'll know that its corresponding textbox is the one whose id is textbox1.
Then the dialogueOpen function would look like this:
private void dailogueOpen(string textBoxId)
{
if (listBox1.SelectedItem == null)
{
MessageBox.Show("Please Select a form");
}
else
{
var selectedItem = (FormItems)listBox1.SelectedItem;
var form2result = new Form2(myDataSet, selectedItem);
var resulOfForm2 = form2result.ShowDialog();
if (resulOfForm2 == DialogResult.OK)
{
TextBox textBox = (TextBox)this.Form.FindControl("MainContent").FindControl(textBoxId);
textBox.Text = resulOfForm2.getValue();
}
}
Where MainContent is the id of container where the textboxes are.
All in all:
I would use a pattern for button and texboxes id.
According to the button being clicked I infer its corresponding texbox id.
Then find the texbox and update its value.
You can have dictionary and one event method on all button clicks
Dictionary<Button, TextBox> dx = new Dictionary<Button, TextBox>;
private void ButtonClick(object sender, EventArgs e)
{
var button = sender as Button;
if (button == null) return;
dx[button].Text = form2result.getValue();
}
and constructor like this:
public ClassName()
{
dx.Add(button1, textBox1);
dx.Add(button2, textBox2);
dx.Add(button3, textBox3);
}
I think the first thing you can do is improve readability by removing the need for the switch statement:
private void dailogueOpen(TextBox textBox)
{
if (listBox1.SelectedItem == null)
{
MessageBox.Show("Please Select a form");
}
else
{
var selectedItem = (FormItems)listBox1.SelectedItem;
var form2result = new Form2(myDataSet, selectedItem);
var resulOfForm2 = form2result.ShowDialog();
if (resulOfForm2 == DialogResult.OK)
{
textBox.Text = form2result.getValue();
}
}
}
private void button1_Click(object sender, EventArgs e)
{
dailogueOpen(textBox1);
}
private void button2_Click(object sender, EventArgs e)
{
dailogueOpen(textBox2);
}
private void button3_Click(object sender, EventArgs e)
{
dailogueOpen(textBox3);
}
private void button4_Click(object sender, EventArgs e)
{
dailogueOpen(textBox4);
}
private void button5_Click(object sender, EventArgs e)
{
dailogueOpen(textBox5);
}
This then gives you a reasonable method signature to introduce the dictionary (suggested by two other people) to map Button to TextBox, which would in turn allow you to use a single event handler (suggested by two other people) for all buttons.
private void button_Click(object sender, EventArgs e)
{
Button button = sender as Button;
if (button == null) return;
String name = button.Text;// Tag, name etc
dailogueOpen(name);
}
private void dailogueOpen(String btnName)
{
if (listBox1.SelectedItem == null)
{
MessageBox.Show("Please Select a form");
}
else
{
var selectedItem = (FormItems)listBox1.SelectedItem;
var form2result = new Form2(myDataSet, selectedItem);
var resulOfForm2 = form2result.ShowDialog();
if (resulOfForm2 == DialogResult.OK)
{
SetTxt(btnName,form2result.getValue());
}
}
}
private void SetTxt(string btnName, string value)
{
int lenght = "Button".Length;
string index = btnName.Substring(lenght); //remove Button
TextBox t = (TextBox)this.Controls.Find("textBox" + index, true)[0];
if (t != null)
t.Text = value;
}

Categories

Resources