I have three TextBoxe1,TextBoxe2 and TextBoxe3 and one main TextBox4 and Button1 when its clicked it will insert TextBox4's value into the clicked (the chosen/selected/clicked one) TextBox. This code Populates all the TextBoxes with the same value.
private void button1_Click(object sender, EventArgs e)
{
TextBox[] array = new TextBox[3] { textBox1, textBox2, textBox3 };
for (int i = 0; i < 3; i++)
{
if (array[i].Focus())
{
array[i].Text = textBox4.Text;
}
}
}
But I want it to take the TextBox4's value and insert into the TextBox2 that I have Clicked on. Like this illu.:
It's better to change the way that you set the value for those TextBox controls and think about another UI, but anyway, if you like to keep it as is, I'll share an idea to satisfy the requirement which you described in the question.
Define a field in form, TextBox selectedTextBox;, then handle Enter event of those 3 TextBox controls and in the handler set selectedTextBox = (TextBox)sender. Then in Click event handler of the button, check if selectedTextBox is not null, then set selectedTextBox.Text = textBox4.Text;:
TextBox selectedTextBox;
public Form1()
{
InitializeComponent();
textBox1.Enter += TextBox_Enter;
textBox2.Click += TextBox_Enter;
textBox3.Click += TextBox_Enter;
button1.Click += button1_Click;
}
void TextBox_Enter(object sender, EventArgs e)
{
selectedTextBox = (TextBox)sender;
}
void button1_Click(object sender, EventArgs e)
{
if(selectedTextBox!=null)
selectedTextBox.Text = textBox4.Text;
}
Make sure you don't attach event handler twice, so to attach event handler, use code editor or designer, not both of them.
Register the Click event of the 3 target TextBoxes to the same handler:
public Form1()
{
InitializeComponent();
textBox1.Click += TransportValueEvent_Click;
textBox2.Click += TransportValueEvent_Click;
textBox3.Click += TransportValueEvent_Click;
}
Inside the handler get the sender (which will be the TextBox that you have clicked) as TextBox and write the value:
private void TransportValueEvent_Click(object sender, EventArgs e)
{
(sender as TextBox).Text = textBox4.Text;
}
Now you don't need the button anymore. The value will be written to the correct TextBox as soon as you click it.
May be you want to avoid deletion if the textBox4 is empty, then you can update the value only if:
private void TransportValueEvent_Click(object sender, EventArgs e)
{
if (!string.IsNullOrWhiteSpace(textBox4.Text))
{
(sender as TextBox).Text = textBox4.Text;
}
}
Related
I am writing a simple calculator script for my C# programming class. It will of course have buttons 0-9 that will update the output textbox to add the number of whatever button is clicked. My problem right now that is I would rather not have to have 10 different click events in my script. I would rather have a loop that cycles through the buttons that will add the same click event to each one and then decide what number to add to the output based on the button.
So right now, I have a click event for the "1" button which is this...
private void btnNum1_Click(object sender, EventArgs e)
{
txtOutput.Text = Convert.ToString(txtOutput.Text + "1");
}
This works fine, but, again, I would rather not have to do this 10 times. How can I create a loop that prevents this?
The button names are btnNum1, btnNum2, btnNum3, etc.
Assuming the button text is just "1", "2" etc you could do this:
private void btnNum_Click(object sender, EventArgs e)
{
var button = sender as Button
txtOutput.Text += button.Content.ToString();
}
Then just apply this event to all the buttons.
Also note you don't need Convert.ToString() as what you are trying to convert is already a string. Using += also cleans up your code a bit.
You could do this to wire-up all of the events in one go:
for (var n = 0; n <= 9; n++)
{
var btn =
this
.Controls
.Find("btnNum" + n.ToString(), false)
.Cast<Button>()
.First();
var digit = n;
btn.Click += (s, e) =>
{
txtOutput.Text = digit.ToString();
};
}
You could enumerate the children controls of your Form/Control, look the type of controls which are type of Button and the name StartWith 'btnNum', with each of these buttons, add a Click event address to btnNum_Click().
Say if all your buttons are contained in a Panel named 'pnlButtons', you could loop all the children like this.
foreach (var control in pnlButtons.Controls)
{
if(control.GetType() == typeof(Button))
{
var button = control as Button;
if (button .Name.StartWith('btnNum'))
{
button.Click += btnNum_Click;
}
}
}
You can use the "Tag" property of the Button control and make an array of Buttons to subscribe to the same event. See sample below:
void InitializeButtons()
{
Button btnNum1 = new Button();
btnNum1.Text = "1";
btnNum1.Tag = 1;
//Button 2..8 goes here
Button btnNum9 = new Button();
btnNum9.Text = "9";
btnNum9.Tag = 9;
Button[] buttons = new Button[]{
btnNum1, btnNum2, btnNum3, btnNum4, btnNum5, btnNum6, btnNum7, btnNum8, btnNum9
};
for (int i = 0; i < buttons.Length; i++)
{
buttons[i].Click += Button_Click;
}
}
void Button_Click(object sender, EventArgs e)
{
Button button = (Button)sender;
int value = (int)button.Tag;
//Do something with value
}
Assuming WinForms, you can recursively search for buttons that start with "btnNum" and wire them up to a common handler like this:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.Load += Form1_Load;
}
void Form1_Load(object sender, EventArgs e)
{
FindButtons(this);
}
private void FindButtons(Control ctl)
{
foreach(Control ctrl in ctl.Controls)
{
if (ctrl.Name.StartsWith("btnNum") && (ctrl is Button))
{
Button btn = (Button)ctrl;
btn.Click += btn_Click;
}
else if(ctrl.HasChildren)
{
FindButtons(ctrl);
}
}
}
private void btn_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
txtOutput.Text = Convert.ToString(txtOutput.Text + btn.Text);
}
}
I've not touched C# in some time, was trying to help a new programmer friend of mine and became utterly stumped by the following:
private void textBox1_TextChanged(object sender, EventArgs e)
{
activateEnterButton();
TextBox t = (TextBox)sender;
string theText = t.Text;
MessageBox.Show("text: " +theText);
}
private void activateEnterButton()
{
bool allGood = true;
foreach (Control control in Controls )
{
if (control is TextBox)
{
string test = ((TextBox)control).Text;
if (test.Length == 0)
{
MessageBox.Show("text: " +test);
allGood = false;
break;
}
}
}
btnEnter.Enabled = allGood;
}
Our goals is utterly simple: We have 5 textboxes and each needs to have some text in them before a button is enabled. When each has text, button is enabled.
When I walk through the code while debugging everything is called okay but no matter how much text I put in the textbox the activateEnterButton never knows it's there. The two MessageBoxes show different output as well: the one in the activateEnterButton never has any, the one in the event handler always does.
Any assistance would be greatly appreciated. Thank you.
I have removed the calls to the activateEnterButton(), I have put guts of that code inside the event handler for textBox5 but the button is still not being enabled.
The answer I accepted didn't give me the functionality I wanted (entering data into textbox5 would make the button active)the following code gave me all the functionality I wanted. And lastly, the reason for my errors were because A) foreach iterates from the last control to the first, and B) the last textbox control I have on the form is a ReadOnly textbox control, its text is always "", hence I was always getting dumped out of my earlier code. At any rate, new code:
private void checkMe()
{
bool allGood = true;
foreach (Control control in Controls)
{
// Make sure the ReadOnly textbox doesn't cause false
if (control.Name.Equals("ReadOnlyTextBox"))
{
// MessageBox.Show("hidden textbox: " + ((TextBox)control).Text);
allGood = true;
}
else if (control is TextBox)
{
string test = ((TextBox)control).Text;
//MessageBox.Show("test: " + test);
if (test.Length < 1)
{
allGood = false;
// MessageBox.Show("All textboxes need input");
break;
}
else
{
allGood = true;
}
}
}
btnEnter.Enabled = allGood;
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
checkMe();
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
checkMe();
}
private void textBox3_TextChanged(object sender, EventArgs e)
{
checkMe();
}
private void textBox4_TextChanged(object sender, EventArgs e)
{
checkMe();
}
private void textBox5_TextChanged(object sender, EventArgs e)
{
checkMe();
}
In your activateEnterButton() method you looping through the controls and if control is textbox; checking whether it has text or not.
Say if textbox1 has fired the textchanged event; how does that guarantee that other textbox has text in it?
You said in your post The two MessageBoxes show different output as well: .. that should be.
say textbox1 have fired textchanged event and so does in textchanged event you have the text displayed in messagebox but in method activateEnterButton() where you are looping through all controls in form there is no guarantee of order like textbox1 .. 5 (in that order loop will check them) and you are breaking out pf loop once it has no text. So does, in your method you don't see any text in messagebox.
Best way of doing it would be as below (consider that you have TextBox 1..5; have the textchanged on TextBox5 only.)
private void textBox5_TextChanged(object sender, EventArgs e)
{
bool allGood = false;
foreach (Control control in Controls )
{
if (control is TextBox)
{
string test = ((TextBox)control).Text;
if (test.Length > 0)
{
allGood = true;
}
else
{
MessageBox.Show("Fill all textbox first");
break;
}
}
}
btnEnter.Enabled = allGood;
}
Hope this helps.
Situation is as follows:
I have a ButtonA, which is currently not enabled.
I have 5 Radiobuttons of which one is always checked.
I want to enable ButtonA when a different Radiobutton gets selected.
I thought about doing something like
private void RadioButton1_CheckedChanged(object sender, EventArgs e)
{
ButtonA.Enabled = true;
}
private void RadioButton2_CheckedChanged(object sender, EventArgs e)
{
ButtonA.Enabled = true;
}
... and so on.
There is probably a more elegant solution and im missing it.
You can use a single method as an event handler for all radiobuttons:
private void RadioButtonChanged(object sender, EventArgs e)
{
ButtonA.Enabled = true;
}
private void HandleEvents()
{
this.RadioButton1.CheckedChanged += RadioButtonChanged;
this.RadioButton2.CheckedChanged += RadioButtonChanged;
this.RadioButton3.CheckedChanged += RadioButtonChanged;
}
Or a loop to do the same thing:
private void RadioButtonChanged(object sender, EventArgs e)
{
ButtonA.Enabled = true;
}
private void HandleEvents()
{
foreach(var rb in new[] {RadioButton1, RadioButton2, RadioButton3})
rb.CheckedChanged += RadioButtonChanged;
}
Or even a lambda event handler set in a loop:
private void HandleEvents()
{
foreach(var rb in new[] {RadioButton1, RadioButton2, RadioButton3})
rb.CheckedChanged += (o,e) => ButtonA.Enabled = true;
}
How about just having 1 event handler like this:
private void RadioButton_CheckedChanged(object sender, EventArgs e)
{
ButtonA.Enabled = true;
}
Then you can use the form designer to assign this method name to the CheckedChanged events of all the radio buttons.
This will save you having to repeat the code for each radio button.
Another trick is to add all your radio buttons to a group box or panel in the designer, then they will all be children of that control.
Then you can add the following code to your Load event handler for the form:
foreach(var radioButton in radioGroupBox.Controls.Cast<Control>()
.Where(i => i is RadioButton)
.Cast<RadioButton>())
{
radioButton.CheckedChanged += RadioButton_CheckedChanged;
}
This way, if you add more RadioButtons to the group, you don't need to change any code.
I'm trying to create a matching game that consists of 12 buttons. The program assigns a random string from an array that has 12 strings in it. When the button is pressed, the tag is passed to the button.text.
What I'm trying to accomplish now is, for example. If I press "button 1", the text of it changes to "Chevy Camaro". If I press "button 4" next, I want the button1.text to revert back to saying "button 1", rather than it's tag value of "Chevy Camaro". And in like fashion, since "button 4" was pressed, I would like it to show the tag.....
Each button has similar code to it, besides the button #, which of course changes based on the button that's being used.
I'm unsure how to state that, if button is the current active item, then show it's tag property, otherwise, revert back.
private void button4_Click(object sender, EventArgs e)
{
button4.Text = button4.Tag.ToString();
buttoncount++;
label2.Text = buttoncount.ToString();
}
Thanks in advance for all of your help. Slowly learning this stuff.... =p
You could keep track of the last button that was clicked:
public partial class Form1 : Form
{
Button lastButton = null;
int buttoncount;
public Form1()
{
InitializeComponent();
button1.Tag = "Ford Mustang";
button2.Tag = "Ford Focus";
button3.Tag = "Chevy Malibu";
button4.Tag = "Chevy Camaro";
button1.Click += button_Click;
button2.Click += button_Click;
button3.Click += button_Click;
button4.Click += button_Click;
//etc...
}
void button_Click(object sender, EventArgs e)
{
if (lastButton != null)
{
SwitchTagWithText();
}
lastButton = sender as Button;
SwitchTagWithText();
buttoncount++;
label2.Text = buttoncount.ToString();
}
void SwitchTagWithText()
{
string text = lastButton.Text;
lastButton.Text = lastButton.Tag.ToString();
lastButton.Tag = text;
}
}
Could you use a RadioButton control with its appearance set to button? Replace all buttons with these, put them in a GroupBox and the 'reverting' of appearance when clicked off can be automatically handled. To update the text, a simple event handler like below will do;
private void MakeButton()
{
RadioButton rb = new RadioButton
{
Appearance = Appearance.Button,
Tag = "Chevy Camero"
};
rb.CheckedChanged += rb_CheckedChanged;
}
private void rb_CheckedChanged(object sender, EventArgs e)
{
RadioButton clickedButton = sender as RadioButton;
string currentText = clickedButton.Text;
clickedButton.Text = clickedButton.Tag.ToString();
clickedButton.Tag = currentText;
}
I have a win app form with 3 text boxes and buttons as dial pad (it's a touchscreen app)...
When a dial pad button is pressed I want to check which one of these 3 text boxes has focus, and append text to it.
Something like:
if (tbx1.Focused == true)
{
tbx1.Text += "0";
}
else if (tbx2.Focused == true)
{
tbx2.Text += "0";
}
else
{
tbx3.Text += "0";
}
But this doesn't work... It appends text to tbx3 all the time.
Any suggestions?
Thanks :)
The problem arises when you click the button, the button will gain focus and not any of your textboxes.
What you can do is subscribe to the LostFocus event and remember what textbox had the focus last.
Something like:
private TextBox lastFocused;
private void load(object sender, EventArgs e){
foreach (TextBox box in new TextBox[] { txtBox1, txtBox2, txtBox3 }){
box.LostFocus += textBoxFocusLost;
}
}
private void textBoxFocusLost(object sender, EventArgs e){
lastFocused = (TextBox)sender;
}