Tooltip-textbox in C# - c#

I have applied a ToolTip to textbox in C# such that the textbox has to accept the name of the user. In the ToolTip, I have types the instructions that only alphabets are welcome in the textbox, which is a success. But what I want is to make that ToolTip disappear when the user starts to type his name or moves to another textbox. The coding so far is;
ToolTip tt = new ToolTip();
String message = "Trying";
private void txtName_Enter(object sender, EventArgs e)
{
if (txtName.Text == String.Empty)
{
tt.Show(string.Empty, txtName, 0);
tt.Show(message, txtName, new Point(0, -2 * txtName.Height));
}
}
Help?

There is an event on the textbox called TextChanged. It fires as soon as the Text property of the control changes in value. Typing a character does change the Text property and therefor triggers the event.
Leveraging that knowledge, you can dismiss the tooltip as soon as Text is no longer empty like so:
private void txtName_TextChanged(object sender, EventArgs e)
{
var ctl = (Control) sender; // sender is a control
if (!String.IsNullOrEmpty(ctl.Text))
{
tt.SetToolTip(ctl, String.Empty);
}
}
Notice that this implementation can be used generically, by any control that you want to have this behavior.

Related

Why I can not change focus?

Im making a calculator.and for the buttons that type numbers, I wrote a condition that if the focus was on text box 1, it would enter the text there, if not, it would enter text box 2. But unfortunately the code does not work and I dont understand the problem.
(WindosForm(.Net framework))
if (textBox1.Focus() == true)
{
textBox1.Text = textBox1.Text + "1";
}
else
{
textBox2.Text = textBox2.Text + "1";
}
Subscribe to "Enter" event for your two textbox and save it. Use the same method for the two textboxes.
TextBox focusedTB;
private void textBox_Enter(object sender, EventArgs e)
{
focusedTB = sender as TextBox;
}
...
this.textBox1.Enter += new System.EventHandler(this.textBox_Enter);
...
this.textBox2.Enter += new System.EventHandler(this.textBox_Enter);
Now you know the last textbox that got focus.
private void button1_Click(object sender, EventArgs e)
{
focusedTB.Text += "1";
}
Your code appears to be attempting to check if the control is focused. The correct way to do that is:
if (textBox1.Focused)
{
// Because 'Focused' is a property. 'Focus()' is a method.
textBox1.Text = textBox1.Text + "1";
}
.
.
.
The answer to your question Why I can not change focus? is that textBox1 receives the focus every time you call this:
if (textBox1.Focus())
As mentioned in one of the comments, here's how the Focus method works:
// Summary:
// Sets input focus to the control.
//
// Returns:
// true if the input focus request was successful; otherwise, false.
[EditorBrowsable(EditorBrowsableState.Advanced)]
public bool Focus();
Note: This is a copy-paste of metadata that you can look at by right-clicking over Focus() in your code and selecting Go to Definition then expanding the definition.
I think you talk about Windows Form ?
You cannot manage like this but use event "Enter" of your textboxes, when you click inside the textbox, you give the focus to this textbox and you can do anything inside. Here I put the right focuses TextBox in a variable.
private TextBox _textBoxFocused; //this is always the righ TextBox
private void textBox1_Enter(object sender, EventArgs e)
{
_textBoxFocused = textBox1;
}
private void textBox2_Enter(object sender, EventArgs e)
{
_textBoxFocused = textBox2;
}

If the cursor is in a specific textBox, delete only that textBox text with a button click

I am building a simple calculator. I have three textBoxes: textBox1 (first operand), textBox2 (second operand), and textBox3 (result). I have numerous operand functions that can be performed. I also have a button that will clear all fields, as well as other functions.
I am having difficulty with the code needed to delete the text in a specific textbox with a button only when the cursor is in that textbox.
Ex: if cursor is in textBox1, the button only clears that textbox.
Any help is much appreciated.
Thanks.
When the Button is clicked it will gain focus.
So you need to keep track of which of your TextBoxes got focus last.
Create a class level variable for that:
TextBox focusedTextBox = null;
Now hook up this event with the Enter event of all three TextBoxes:
private void textBoxes_Enter(object sender, EventArgs e)
{
focusedTextBox = sender as TextBox;
}
Then this will only clear the one your user was in last:
private void buttonClearCurrent_Click(object sender, EventArgs e)
{
if (focusedTextBox != null) focusedTextBox.Text = "";
}
In this case you have to use the Focused property in the textbox.
But you need to make a loop to identify which text box is focused.
like:
var focusedControl;
foreach(var control in this.Controls)
{
if(control is TextBox)
{
if(control.Focused)
{
focusedControl = control;
break;
}
}
}
You can use event: "MouseHover" or "MouseClick" and set textBox1.Text=""

How to convert slider value to textbox

i'm new in C# and I want to convert value of slider to textbox. One option i found is set binding for text box, but I need send value in event.
I tried some solutions, but not worked.
private void sliderName_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
Slider sliderName = sender as Slider;
TextBox textBoxName = new TextBox();
textBoxName.Text = sliderName.Value.ToString();
}
Thanks for helping and be patient with me. :)
You're creating a new TextBox, but not positioning it anywhere.
You should have your TextBox already on your form, and reference it by the name you gave it at design-time in the IDE. For example, if you just drop a TextBox on the form, the IDE will give it a name like textBox1, and you use it by that name:
private void sliderName_ValueChanged(object sender,
RoutedPropertyChangedEventArgs<double> e)
{
// Don't use the same name used on the form if you're
// declaring a variable here. Use a name that's local to
// this event.
Slider slide = sender as Slider;
// Use the IDE-set name here.
difficultyBox.Text = slide.Value.ToString();
}
Updated to reflect name change based on comment below.
OR an even faster way:
private void sliderName_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
textBox1.Text = ((Slider)sender).value.ToString();
}
The only difference between this post, and Ken's Post is that I am casting the sender as a slider while setting the text property of textBox1.
Just showing you different options and a different way of doing the same thing.
Your approach would probably work, except that you are declaring a new TextBox local to this event handler, so you'll never see anything on the screen.
Try setting the .Text property of a TextBox in your form;
private void sliderName_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
Slider sliderName = sender as Slider;
difficultyBox.Text = sliderName.Value.ToString();
}

How to validate array of text boxes

I am using c# winform.
I have 2dimensional array of text boxes I want them to accept only Letters from A-I I've created the method but that works for only one text box.
Here is my code:
textbox[i,j].Validated+=new EventHandler(TextBox_KeyPress);
private void TextBox_KeyPress(object sender, EventArgs e)
{
bool bTest = txtRegExStringIsValid(textbox[1,1].Text.ToString());
ToolTip tip = new ToolTip();
if (bTest == false)
{
tip.Show("Only A-I", textbox[1,1], 2000);
textbox[1,1].Text = " ";
}
}
private bool txtRegExStringIsValid(string textToValidate)
{
Regex TheRegExpression;
string TheTextToValidate;
string TheRegExTest = #"^[A-I ]+$";
TheTextToValidate = textToValidate;
TheRegExpression = new Regex(TheRegExTest);
if (TheRegExpression.IsMatch(TheTextToValidate))
{
return true;
}
else
{
return false;
}
}
Can anyone please guide what should I do make this code work for all text boxes?
if this works for textbox[1,1] you could register your private void TextBox_KeyPress(object sender, EventArgs e) as eventhandler for all your textboxes and instead of textbox[1,1] you could use ((TextBox)sender)
i want text boxes to accept only letters from a-i actually i am trying to make sudoku
There's a much simpler solution than regular expressions, and you don't even need to handle the Validated event to implement it.
In a situation like this, where there are only certain characters that you want to prevent the user from entering, handling the KeyDown event is a much better solution. The user gets immediate feedback that the letter they tried to enter was not accepted. The alternative (the Validating and Validated events) actually wait until the user tries to leave the textbox to rudely alert them that their input was invalid. Especially for a game, this tends to break concentration and isn't particularly user-friendly.
Doing it this way also makes it irrelevant which individual textbox raised the event. Instead, you will handle it the same way for all of the textboxes—by completely ignoring all invalid input.
Here's what I'd do:
First, attach a handler method to your textbox's KeyDown event. You can do this from the Properties window in the designer, or you can do it through code, as you have in the question:
textbox[i,j].KeyDown += TextBox_KeyDown;
Then, you need to put the logic into your event handler method that determines if the key that the user just pressed is in the allowed range (A through I), or outside of it:
private void TextBox_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
// Determine if the keystroke was a letter between A and I
if (e.KeyCode < Keys.A || e.KeyCode > Keys.I)
{
// But allow through the backspace key,
// so they can correct their mistakes!
if (e.KeyCode != Keys.Back)
{
// Now we've caught them! An invalid key was pressed.
// Handle it by beeping at the user, and ignoring the key event.
System.Media.SystemSounds.Beep.Play();
e.SuppressKeyPress = true;
}
}
}
If you want to restrict the user to typing in only one letter, you can add code to handle that in the above method, or you can take an even simpler route and let the textbox control handle it for you automatically. To do that, set the MaxLength property of the textbox to true, either in the designer or through code:
textbox[i,j].MaxLength = true;
Check the text of the sender instead of whatever textbox[1,1] is.
Use the sender parameter of the event handler to identify the textbox responsible for the event.
The first thing that will help you is casting the sender of your event to a TextBox like this:
(Also, as Cody Gray said, this is a TextBox_Validated event, not a KeyPress event so I've renamed it appropriately)
private void TextBox_Validated(object sender, EventArgs e)
{
TextBox tb = sender as TextBox()
if (sender == null)
return;
bool bTest = txtRegExStringIsValid(tb.Text.ToString());
ToolTip tip = new ToolTip();
if (bTest == false) {
tip.Show("Only A-I", tb, 2000);
tb .ext = " ";
}
Next you need to actually get into that code for every textbox. There are two obvious approaches to that, you can either assign the eventhandler to each textbox in the array or you can use a custom textbox which always does this validation and then add that to your array.
Assign eventhandler to textboxes
foreach(var tb in textbox)
{
tb.Validated += new EventHandler(TextBox_KeyPress);
}
Create custom textbox control
Create the custom text box control (Add a user control to the project) and then just use it exactly as you would a normal textbox.
public partial class ValidatingTextBox: TextBox
{
public ValidatingTextBox()
{
InitializeComponent();
}
protected override void OnValidating(CancelEventArgs e)
{
bool bTest = txtRegExStringIsValid(this.Text.ToString());
ToolTip tip = new ToolTip();
if (bTest == false)
{
tip.Show("Only A-I", this, 2000);
this.Text = " ";
}
}
private bool txtRegExStringIsValid(string textToValidate)
{
// Exactly the same validation logic as in the same method on the form
}
}

Modifying a TextBox control on the Leave event prevents tabbing out of the control

I've got a standard TextBox control which I'm trying to have mimic the "soft descriptions" like those found in the title and tags boxes on StackOverflow. Essentially, when the user's focus enters the control, it hides the description ("Username") in this case, and sets alignment and color to be that of a standard text control. When the user leaves the textbox, I want to check if the user actually entered anything, and put the username display back up otherwise.
For example:
private void tbUsername_Enter(object sender, EventArgs e)
{
if (tbUsername.TextAlign == HorizontalAlignment.Center)
{
tbUsername.TextAlign = HorizontalAlignment.Left;
tbUsername.ForeColor = SystemColors.ControlText;
tbUsername.Text = String.Empty;
}
}
private void tbUsername_Leave(object sender, EventArgs e)
{
if (tbUsername.Text == String.Empty)
{
tbUsername.TextAlign = HorizontalAlignment.Center;
tbUsername.ForeColor = SystemColors.InactiveCaption;
tbUsername.Text = "Username";
}
}
Unfortunately, when I setup these events, the user cannot tab out of the username control. The control simply flickers and control returns to the textbox control itself until the user has entered something, skipping over the event body.
If I call this.SelectNextControl() in the event, then the event enters an infinite loop.
Does anybody see what I'm doing wrong?
Looks like another way around it (Using Reflector to see that it does refocus back on the Control if the focus was there to begin with). I think it is a bug, but looks like they were just reusing RecreateHandleCore function to redraw the text. So another way would be to focus off the textbox first, then continue:
private void LeaveEvent(object sender, EventArgs e)
{
if (String.IsNullOrEmpty(tbUsername.Text))
{
tbUsername.Text = USER_NAME;
tbUsername.ForeColor = SystemColors.InactiveCaption;
this.Focus();
tbUsername.TextAlign = HorizontalAlignment.Center;
}
}
Setting the TextAlign property on the TextBox control returns focus back to that control. That seems like a bug.
Here is a quick fix:
tbUsername.Enabled = false;
tbUsername.ForeColor = SystemColors.InactiveCaption;
tbUsername.Text = "Username";
tbUsername.TextAlign = HorizontalAlignment.Center;
tbUsername.Enabled = true;
(although somewhat of a hack around unexpected behavior). Simply disable the control before changing the alignment. Another "fix" would be to keep things aligned left, or to measure how many spaces to insert to simulate centering the text.
Use BeginInvoke
private void tbUsername_Leave(object sender, EventArgs e)
{
BeginInvoke(new MethodInvoker(OnLeave));
}
private void OnLeave()
{
if (tbUsername.Text == String.Empty)
{
tbUsername.TextAlign = HorizontalAlignment.Center;
tbUsername.ForeColor = SystemColors.InactiveCaption;
tbUsername.Text = "Username";
}
}

Categories

Resources