Get the name of a focused textbox in a form c# - c#

First of all, I know that there are probably better solutions and I am very willing to listen to those solutions. I have searched around the internet looking for a problem like this but am unable to find one that works so far. I have multiple textboxes on a form, when the user clicks on the textbox I run a method that finds out which textbox is focused, gets the tag of that textbox and the name of the textbox both as strings (TextboxX and test). My goal is to mask the textboxes with for example 'Email' and when the user clicks on the textbox the textbox forecolor changes to black and the textbox text is null, with as little code as possible.
Here is the code i have for that.
public void masked()
{
if (textboxX.Text == test)
{
textboxX.ForeColor = Color.Black;
textboxX.Text = "";
}
else
{
textboxX.Select(0, textboxX.Text.Length);
}
}
When the textbox is clicked this is what it does currently.
private void txtSignup_email_Click(object sender, EventArgs e)
{
textboxX = txtSignup_email;
test = "Email";
masked();
}
The reason for this is that I have 7 textboxes, it will save me about 14 lines of code that is actually not necessary. Thanks in advance.

OK there are a few things that can be done better.
First of all you can use Password instead of TextBox which is automatically masked and can't be seen if I understand you requirement correctly.
Second thing is what ainwood said in the comment you can point all clicked or focused events of your textboxes to a single method. Event handler methods have two parameters sender and e. The former is of type object and shows who called this method in your case you can cast is as a TextBox and that will be calling textbox. The cast operation is like this:
var textBox = sender as TextBox;
if (textBox != null)
{
//Do what you want with textBox here
}
Also if you use the new C# 7 you can do (Which is not any different internally just better to read):
if (sender is TextBox textBox)
{
//Do what you want with textBox here
}

Related

Change Value of a Dynamically Created Text Box when button is clicked C#

I have dynamically created a button using a function I made which is meant to increase the value of another button created using a similar function. I'm able to retrieve the name of the dynamically created textbox, but since it is dynamically created, I can't reference it.
I've tried to pass the textbox through as a parameter, but it doesn't appear that I'm able to pass extra parameters:
Button ButtonDecreaseValue= addButton(ItemName, "-");
TextBox TextBoxItemAmount = addTextBox(ItemName, "0");
So, how would I change the value of textbox one when ButtonRemoveItem is clicked?
I've created an event handler for the button, like so:
ButtonIncreaseValue.Click += new EventHandler(ItemDecreased);
But, inside the event handler, I'm unsure how I would change the textbox name.
private void ItemDecreased(object sender, EventArgs e)
{
Button currentItem = (Button)sender;
int ItemNo = Convert.ToInt32(currentItem.Tag);
DataRow ItemInfo = getItemDetails(ItemNo);
ItemInfo[0].ToString();
}
When clicking the button, the corresponding textbox should decrease in value.
Assuming this is Windows Forms
You said you have the name of the TextBox? You should be able to find it with that.
private void ItemDecreased(object sender, EventArgs e)
{
string textBoxName = HoweverYouGetTheDynamicTextBoxName();
// Assumptions:
// 1. ItemDecreased is a method on a Form or a UserControl.
// 2. There is only one TextBox with the given name in the Form or UserControl.
// 3. The TextBox is added to the Form or UserControl's Controls property.
TextBox tb = Controls.Find(textBoxName, true).OfType<TextBox>().SingleOrDefault();
if (tb is null)
{
// Couldn't find the text box for some reason.
}
// tb references the dynamically created text box.
}

How call the Text_Changed Event for multiple text box controls on a form in C# winforms

I have form that has about 20 TextBox controls and I would like to fire the Text_Changed event with out adding the event for each individual text box. Is there a way to loop through the text boxes to fire this event? What I am trying to do is clear a label control when the text changes. Instead of displaying a message box, for error descriptions, I use a label control to display the message. I also set it up where if a text box has invalid data, I select all text and give focus to that TextBox so when user re-enters information the label control clears the message.
Edit:
To clear up some confusion, here is some of my code from my validation method
if (txtBentLeadsQty.Text == "")
{
//ValidData = true;
BentLeadsCount = 0;
}
else
{
if (int.TryParse(txtBentLeadsQty.Text.Trim(), out BentLeadsCount))
ValidData = true;
else
{
ValidData = false;
lblError.Text = "Bent Lead Qty must be a numeric value";
txtBentLeadsQty.SelectAll();
txtBentLeadsQty.Focus();
}
}
I already have a way to check for numeric values, and I put code in to select all text entered and gave focus if the values are not numeric, I just want to have a way to clear the Label control when the the text is changes like if the user hit backspace or starts typing that why if the error occurs, I highlight all the text in that TextBox if it is not valid. I can do this if I put code in every text boxes TextChanged event, but to save coding I was wondering if there is way to clear the label control if any of the text boxes throws an error from my validation method instead of adding individual events for 20 text boxes.
Note: Not all text boxes will have data entered, these are quantity text boxes I put code in to assign a 0 to the variable if the TextBox in null.
You can use the following code:
private void Form1_Load(object sender, EventArgs e)
{
foreach (Control ctrl in this.Controls)
{
if ((ctrl as TextBox) != null)
{
(ctrl as TextBox).TextChanged += Form1_TextChanged;
}
}
}
private void Form1_TextChanged(object sender, EventArgs e)
{
MessageBox.Show((sender as TextBox).Name);
}
I'm assuming you want to add the same handler to all textboxes in the form dynamically, i.e. without having to add them for each text box in the visual editor (or code).
If so, this might be what you need:
// Iterate over all controls in the current form:
foreach (var ctl in Controls)
{
// Check if the current control is a textbox
// (will be null if it is of another type)
var txtBox = ctl as TextBox;
if (txtBox != null)
{
txtBox.TextChanged += YourMethod();
}
}
Sounds like you want to programmatically fire the method on each text box.
First, create an array of around 20 text boxes.
var textBoxes = new []{textBox0, textBox1, textBox2};
Loop through the each box and call the text changed method
foreach(var textBox in textBoxes)
{
TextChangedMethod(textBox);
}
If the method you are calling was generated by Visual Studio, it will take a second parameter for EventArgs. You can simply pass a null value for that.
TextChangedMethod(textBox, null);
Create a method, something like this:
public void TextChanged(object sender, EventArgs e)
{
//Text-changed code here.
}
At this point you can click on each text box on your form and add your new method to the event you want to occur. Click a text box on your form, and click the thunderbolt icon in the properties menu and scroll down to "TextChanged" event. Change that drop down on that event to your new method.
OR
Add the event at run time after you initialize the forms components:
textBox1.TextChanged += new EventHandler(TextChanged);
textBox2.TextChanged += new EventHandler(TextChanged);
textBox3.TextChanged += new EventHandler(TextChanged);
This could be done easier if you add all the text boxes to an array, and loop through them with a foreach to add the event to each one. You could also just grab all the text boxes from the form and loop the same way, though I don't know if you have other controls/text boxes that would make you avoid this method.
Use a foreach statement.
Example
List<TextBox> TextblockCollection = null;//You have to add them all individually to the list
foreach (var text in TextblockCollection)
{
//Change the text to the same thing, firing the method
text.Text = text.Text
}
So you want to check when any of the text boxes are changed, then check if the new input in the changed textbox is a number (I'm assuming an integer) and then display a message in a label if it's not a number.
public MainForm()
{
InitializeComponent();
foreach (Control control in this.Controls)
{
if (typeof(control)==typeof(TextBox))
{
(control as TextBox).TextChanged += CommonHandler_TextChanged;
}
}
}
private void CommonHandler_TextChanged(object sender, EventArgs e)
{
int number;
string input=(sender as TextBox).Text;
bool isnumber=false;
isnumber = Int32.TryParse(input, number);
if(isnumber==false)
{
yourLabel.Text = "This textbox contains an incorrect number: "
+(sender as TextBox).Name;
}
else{ /*use the number*/ }
}

Move Focus to next Control in WPF

Suppose I have a DataGrid and a Button. CanUserAddRows is set to True. Let this dataGrid have two DataGridTextColumns namely "Name" and "Age".
Now if user takes the following actions :
He adds name as XYZ and Age as 20. Then he press enter. So a new row will be added to the datagrid.
He adds name as ABC and Age as 12. Then he press enter. So a new row will be added to the datagrid.
He keeps name empty and press Enter or TAB then I want to move focus to Button instead of next cell of datagrid.
I have watched many questions but I don't get the logic of if user left the name empty and how do I move focus to Button instead of next cell.
Use DataGridView.SelectedCells[0] so you can retrieve the value of the selected cell (assuming you can only select one).
To get the actual string inside, you will have to cast the content to a proper WPF object, like TextBlock.
myCell.Column.GetCellContent(cell.Item) as TextBlock
Then in a PreviewKeyDown event handler (KeyDown having known issues in DataGridView), you can use button.Focus(). (more about those issues)
//...
myDataGrid1.PreviewKeyDown += myDataGrid1_KeyDown;
//...
void myDataGrid1_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
{
if (e.Key == System.Windows.Input.Key.Enter)
{
var cell = myDataGrid1.SelectedCells[0];
TextBlock cellContent = cell.Column.GetCellContent(cell.Item) as TextBlock;
if (cellContent != null)
{
if (String.IsNullOrWhitespace(cellContent.Text))
button.Focus();
}
}
}
About getting the column's name, it's another question, for which you can find answer here for example.
As a side note, you're not really supposed to interact directly with a DataGridView cells' values, since it's meant to be bound with a data source from which you should retrieve the data you want to test. However, you can search a bit for helper methods that can help you get what you want.
You can define a handler for the DataGrid.KeyDown event, as:
void myDataGrid1_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
{
if (e.Key == System.Windows.Input.Key.Enter)
{
button.Focus();
}
}

c# format textboxes to currency when they lose focus

I have several lists of text boxes on a form each representing a column of a database. I want to update the form each time the user exits one of the boxes for price. the name of this list is priceBox[]. I am aware of the lostFocus event but I cant seem to figure a way to get it to work for a collection and this list can grow so I cant have a fixed number. I dont have any code for this yet. if it helps the text box controls are contained in a panel named panel1.
I have tried searching and cant find anything on this. only for singular instances, like updating 1 text box.
sorry if this is a duplicate but I did try to search. also I am new to c#.
thanks.
One approach is adding a ControlAdded handler to the panel, so every time a new textbox is added, it automatically adds LostFocus handler for it. Step-by-step below:
For your panel you bind a handler ControlAdded event, which would be something like:
private void Panel1_ControlAdded(object sender, ControlEventArgs e)
{
var tb = e.Control as TextBox;
if (tb != null)
{
tb.LostFocus += new EventHandler(TextBox_LostFocus);
}
}
Then in TextBox_LostFocus you can add whatever logic you want
void TextBox_LostFocus(object sender, EventArgs e)
{
var tb = sender as TextBox;
if (tb != null)
{
// modify tb.Text here, possibly like this...
tb.Text = String.Format("{0:C}", Decimal.Parse(tb.Text));
}
}
To update all existing controls (not tested)
foreach (TextBox in panel1.Controls)
{
tb.LostFocus += new EventHandler(TextBox_LostFocus);
}

Groupbox check for changes event

I have a DataGridView and a GroupBox control containing a few ComboBoxes.
Depending on what is selected in the ComboBoxes, the elements in the grid changes.
Is there a way to say
If (Something Changes Within The GroupBox)
{
//Update the grid
}
(Without writing a OnSelectedIndexChange event for every boxes)
I don't want the code for the updating part, I just need an event or something I could use to check if a the value of a control has changed within the GroupBox.
Any Idea ?
Update
Ok I think I didn't explained it the right way.
Forget about the ComboBox.
Let's say I have a bunch of controls in a GroupBox is there a way to say :
As soon as the value of one of the control changes, create an event.
You could hook up each combo box SelectedIndexChanged event to one method:
comboBox1.SelectedIndexChanged += new System.EventHandler(GroupBoxComboBoxChange);
comboBox2.SelectedIndexChanged += new System.EventHandler(GroupBoxComboBoxChange);
comboBox3.SelectedIndexChanged += new System.EventHandler(GroupBoxComboBoxChange);
comboBox4.SelectedIndexChanged += new System.EventHandler(GroupBoxComboBoxChange);
Or using LINQ to setup an event handler for any combo box selection change:
GroupBox.Controls.OfType<ComboBox>.ForEach(cb => cb.SelectedIndexChanged += new System.EventHandler(GroupBoxComboBoxChange));
Answer to your update: You are looking for a ControlValueChanged() event. I think the problem here is that all controls are different. What defines a "ValueChanged" event for a ComboBox isn't necessarily the same for a TextBox. It would be a semantic challenge and not very clear. Hope this makes sense.
There is no "something inside me changed" for GroupBoxes, but you can "cheat" and DYI like this (it's just a proof-of-concept without error checking and the sort):
// In a new Windows Forms Application, drop a GroupBox with a ComboBox and a CheckBox inside
// Then drop a TextBox outside the ComboBox. Then copy-paste.
// this goes somewhere in your project
public static class handlerClass
{
public static string ControlChanged(Control whatChanged)
{
return whatChanged.Name;
}
}
// And then you go like this in the Load event of the GroupBox container
void Form1_Load(object sender, EventArgs args)
{
foreach (Control c in groupBox1.Controls)
{
if (c is ComboBox)
(c as ComboBox).SelectedValueChanged += (s, e) => { textBox1.Text = handlerClass.Handle(c); };
if (c is CheckBox)
(c as CheckBox).CheckedChanged += (s, e) => { textBox1.Text = handlerClass.Handle(c); }; }
}
}
Since every Control has its own "I'm changed!" kind of event, I don't think it can be any shorter as far as boilerplate goes. Behavior is a mere sample that writes the name of the control that changed in a ComboBox
GroupBoxes are usually just decorative unless they are managing radio buttons or check boxes, so expecting them to be aware of changes made to combo boxes is not something easily done out of the box. If I may, why not code a method that does what you want it to do, and then call that method from all your combo boxes' SelectedIndexChanged events?

Categories

Resources