textbox focus check - c#

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

Related

How can I enter data to Textboxes sequentially

I'm a newbee to C# and I'm trying to write code in Visual Studio. I need your help.
I want to enter numbers to 20pcs textbox in tabpage1 in form by hand held barcode scanner in C#. Cursor must go to next textbox after reading from barcode scanner. And I will check the read data with some conditions (between 2 values numbers etc) for every textbox.
I write some code but it makes code size big. I think it must be easy way I need your comment and help.
The barcode scanner reads the barcode and sends barcode number + enter code. And barcode scanner read and put number to first textbox then pass to next textbox and it repeating for all textbox - how can I do this easily?
Thanks
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
textBox1.SelectAll();
textBox2.Focus();
e.Handled = true;
}
}
private void textBox2_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
textBox2.SelectAll();
textBox3.Focus();
e.Handled = true;
}
}
.
.
.
.
private void textBox20_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
textBox20.SelectAll();
textBox1.Focus();
e.Handled = true;
}
}
The good news is that the sender object is always that control which has triggered the event. In other words the sender is a reference to one of your TextBoxs.
You can take advantage of this fact and you can have a single event handler, which could be reused for multiple events.
private void textBoxN_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
var textBoxCurrent = sender as TextBox;
textBoxCurrent.SelectAll();
//TODO: set focus for next
e.Handled = true;
}
}
So, the next question is how to get a reference to the next TextBox?
You can use the Tag property for this.
In case of WinForms the Control object has a property called Tag.
In case of WPF the FrameworkElement object has a property called Tag.
In both cases this property is an object so we can store anything in that. If we populate that with a reference to the next TextBox then the generic handler would look like this:
private void textBoxN_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
var textBoxCurrent = sender as TextBox;
textBoxCurrent.SelectAll();
var textBoxNext = textBoxCurrent.Tag as TextBox;
textBoxNext.Focus();
e.Handled = true;
}
}
What's left?
Populate the Tag properties
Subscribe to the KeyDown events
private void Init()
{
var textBoxes = new List<TextBox> { TextBox1, TextBox2, ..., TextBox20 };
foreach(var item in textBoxes.Select((textBox, index) => (textBox, index))
{
var nextIdx = (item.index + 1) % textBoxes.Count;
item.textBox.Tag = textBoxes[nextIdx];
item.textBox.KeyDown += textBoxN_KeyDown;
}
}
We have created an iterator here which is deconstructed into a textbox and an index of this TextBox in the textBoxes collection.
We have calculated the next TextBox index into the nextIdx. Then we have wired up everything.
here is an idea for solving
class Program
{
LinkedList<TextBox> _textBoxes;
ctor()
{
_textBoxes = new LinkedList<TextBox>();
_textBoxes.List.AddLast(textbox1);
_textBoxes.List.AddLast(textbox20);
}
private void textBox_KeyDown_justOneCommonHandle(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
var textboxCurrent = _textBoxes.Current;
// make sure that Value is the sender
textboxCurrent.SelectAll();
_textBoxes.MoveNext();
var textboxNext = _textBoxes.Current;
// check the end of list
textboxNext.Focus();
e.Handled = true;
}
}
}
# Peter Csala, #Ivan Stavenchuk
Thanks for your idea and help. I solved my problem as shown below
I added a main Textbox (textBox21) and used keydown event of main textbox
private void textBox21_KeyDown(object sender, KeyEventArgs e)
{
TextBox tb = new TextBox();
tb.Name = "textBox" + i.ToString();
if (e.KeyCode==Keys.Enter)
{
TextBox tbx = this.Controls.Find(tb.Name, true).FirstOrDefault() as TextBox;
tbx.Text = textBox21.Text ;
i++;
if (i>20) i=1;
textBox21.SelectAll();
}
}

Populate TextBox's value to a specific Textbox

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

How do I add click events to all buttons that have names starting with a certain string in C#?

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

c# - Hide button text when another button is clicked

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

Binding an event to all TextBox 'es in a winform

I have a lot of TextBoxes in my single winform application. I am looking for a way to bind a single event method to all those textboxes when the form loads or in its constructor, so I dont add the event to every single textbox in designer.
In the event, I want to detect the ENTER key and then programmatically click on a button:
private void ApplyFilterOnEnterKey(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
btnApplyFilters_Click(this, null);
}
}
Now the problem is how can I loop over all textboxes in my form and bind them to the above method? My textboxes are everywhere, inside nested tablelayoutpanels or nested normal pannels. How this loop will look like and where should I put it? In form constructor or in load event?!
Instead of subscribing to every TextBox's KeyDown event, you have two other options that I think are better:
Set your button as the default button of the form by setting AcceptButton property of the form to the button you want to be clicked by pressing Enter key.
Override ProcessDialogKey on your form and check for pressing the Enter key:
protected override bool ProcessDialogKey(Keys keyData)
{
if (keyData == Keys.Enter)
{
// ... do what you want
return true;
}
else
return base.ProcessDialogKey(keyData);
}
Just use the Controls collection and look if the control is a textbox then append the event
Loop through all textboxes (including nested) like this as shown here: Loop through Textboxes
Then,
var allTextBoxes = this.GetChildControls<TextBox>();
foreach (TextBox tb in this.GetChildControls<TextBox>())
{
tb.Click += ApplyFilterOnEnterKey;
}
private void TextBoxFocusIn(object sender, EventArgs e)
{
TextBox textBox = (TextBox)sender;
if (textBox.Text == "Encrypted value here...")
{
textBox.Text = "";
textBox.ForeColor = Color.Black;
}
}
private void TextBoxFocusOut(object sender, EventArgs e)
{
TextBox textBox = (TextBox)sender;
if (textBox.Text =="")
{
textBox.Text = "Encrypted value here...";
textBox.ForeColor = Color.Gray;
}
}
private void BindPlaceHolderInTextbox(Panel contentPanel)
{
foreach(Control control in contentPanel.Controls)
{
if(control.GetType() == typeof(TextBox))
{
control.Text = "Encrypted value here...";
control.ForeColor = Color.Gray;
control.GotFocus += new System.EventHandler(TextBoxFocusIn);
control.LostFocus += new System.EventHandler(TextBoxFocusOut);
}
}
}

Categories

Resources