Toolstripbutton not validating textbox - c#

I have a textbox, a standard button and a toolstrip containing a couple of buttons.
In the validating event of the textbox I coded to check whether it is blank.
If yes then it shows a message 'Enter Value'. When the standard button is clicked while
the textbox is empty, it's validating properly and showing the message but when the
toolstripbutton is clicked it's not validating the textbox and no message is shown. It seems that I've got to write the validation code explicitly in the
toolstripbutton_click event which is too troublesome when there are multiple textboxes and toolstripbuttons on a single form.
What I want to know is whether the textbox_validating can be fired when the toolstripbutton is clicked? Handling toolstrips is really a headache.

The ToolStripItem classes are special, they don't derive from Control. One side-effect of that is that they don't take the focus away from the active control. And that prevents the Validating event from firing.
Several things you can do. You could call the textbox' parent's ValidateChildren() method. Or you could move the focus yourself:
private void toolStripButton1_Click(object sender, EventArgs e) {
btnSave.Focus();
if (btnSave.Focused) btnSave.PerformClick();
}

Write the following in toolstripbutton click event:
Me.Validate()

You can call the textbox_validating procedure from the procedure that handles the toolstripbutton click event, but you may have to add some logic to see if it passed validation before proceeding with the rest of the toolstripbutton_click event. Since you said you have a lot of textboxes to validate, you might want to consider making a Validate() function that returns true or false and checks all of the textboxes. Then all you have to do is check if Validate() = true and call the same function from all of your toolstrip buttons instead of copying the same code over and over again.

Related

On leaving a control, how can I give that control focus again?

I've got TextBoxes in a C# form. The user enters data, and then when they leave the control (almost always by hitting Tab), I check the data to make sure it's valid. If it is invalid, I want to highlight their text so they can immediately fix it rather than having to click it.
Right now, on Control.Leave, I validate their entry. This works just fine. However, since they hit Tab, right after they dismiss the error message, it goes on to the next object, even though I've got ((TextBox)sender).Focus();
How can I have the above line fire after the form Tabs to the next control.
You may want to look into Control.CausesValidation property
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.causesvalidation(v=vs.110).aspx
You can validate the control prior to the user leaving focus rather than waiting on Focus moving itself.
And here's MSDN documentation for Control.Validating event, does a good job at laying out the sequence of events when gaining / losing focus of a Control.
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.validating(v=vs.110).aspx
Notice how Control.Validating and Control.Validated are launched prior to Control.LostFocus. You can perform your validation step prior to allowing the user to lose focus of your Textbox.
There's also a pretty good previous answer on stackoverflow.com which outlines how to do this: C# Validating input for textbox on winforms
If you handle the Control.Validating event, setting e.Cancel to true will stop the change of focus from occurring.
Note that this method will also stop buttons from working, so you may need to set Control.CausesValidation to false on certain buttons.
You will also need the following snippet on the main form to allow the close button to work:
protected override void OnFormClosing(FormClosingEventArgs e) {
e.Cancel = false;
base.OnFormClosing(e);
}
Try using the LostFocus event on the TextBox to Focus it again

How can I know Text changes for textboxes without Textchanged event

In my C# Windows form MyForm I have some TextBoxes.
In these TextBoxes, we have to detect if the TextChanged event occurs,
if there're changes in these TextBoxes and click close button, it will ask if we want to cancel the changes when we close the form.
However, when I run the MyForm, I can't know text change for each textbox caused by user typing for without textchanged event property.
But I am thinking how do I make the TextBox's TextChanged know the
event cuased by user typing without textchanged event?
Thanks for help.
Sorry for my English.
There is no (decent) way of knowing what's typed without a TextChanged or a Leave event.
You need to use one of these events to get the typed content. Doing this enable you to set a "dirty" flag that you can check at close and clear at save.
Comparing old and new value has no point without this cause you won't know what the value should be set to without knowing something was changed.
With one exception: If your original data came from a database you could use the compare old/new approach as you would compare the textbox of that which came from the database.
Update:
Addressing this comment:
"Because Myform have many textboxes and if no text change ,this will
not display the confirm message.If I catch textchanged event for all
textboxes, this is so many code."
You can use a common handler to collect the changes for all textboxes in one single method. Use the sender object (cast it to Textbox) to identify which textbox is changed, if needed, or simply set a dirty flag for whatever textbox has a change.
bool isDirty = false;
void SomeInitMethod() //ie. Form_Load
{
textbox1.TextChanged += new EventHandler(DirtyTextChange);
textbox2.TextChanged += new EventHandler(DirtyTextChange);
textbox3.TextChanged += new EventHandler(DirtyTextChange);
//...etc
}
void DirtyTextChange(object sender, EventArgs e)
{
isDirty = true;
}
void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
if (isDirty) {
//ask user
}
}
// to clear
void Save()
{
SaveMyDataMethod();
isDirty = false;
}
If you have a lot of textboxes in the form loop through the forms control collection and use typeof to address the textboxes. If you have textboxes requiring different approaches use the Tag property of the textbox to distinguish.
A possible approach is using the timer. Have a timer that ticks every 1000 ms (say) and checks the textBox.Text.
A second possible approach is overriding WndProc for the textbox (by inheriting a new class) and handling the change text message. This would be the same as overriding TextBox.OnTextChanged.
Why dont you use a timer which will check after a few intervals if the textboxes do contain any text

How to disable the selection on a TextBox

I want to disable selecting text and clicking in the middle of text in a TextBox, but the user must be able to enter this TextBox and write at the end of earlier text, so I cannot make it ReadOnly or Enable = false.
I try to handle MouseDown and do the following:
input.Select(input.Text.Length, 0);
It helps with placing a cursor in the middle of text, but the user still can make a selection from the end.
I also make a MessageBox() on MouseDown event, but in this case the user cannot click on textBox and write anything.
The last try was to set a focus() in another Control and focus back, after a period of time, but it didn't work at all. User still can make a selection.
How can I do it?
How about this for Click event
Edit: Also do the same for DoubleClick and MouseLeave to cover all cases. You can have a common event handler.
private void textBox1_Click(object sender, EventArgs e)
{
((TextBox) sender).SelectionLength = 0;
}
If it fits the UI/user model, another approach is to use two text boxes: a read-only one with the previous text that the user can see and act on (if that is something he needs to do) and an editable one for the new text along with a button to commit the new text to the read-only text box (and persistence layer).
That approach is not only arguably more user-friendly—the editable box is completely editable rather than just "appendable", which gets confusing when the user hits Backspace—but also requires less fighting with the framework to make the boxes do what you need.
You're not far off with your MouseDown event handler, but probably better to catch MouseUp, as this is the event that will fire when they have finished selecting.
Alternatively, you could catch the SelectionChanged event.
Just put your:
input.Select(input.Text.Length, 0);
code in any of those event handlers.

textbox not losing focus

I have a Form which covers the entire screen. I have a textbox on it which is normally hidden but appears when a user clicks, drags mouse and then leaves. After that user can enter any value in the text box. Once entered, ideally user should be able to click outside of textbox and then the normal service should resume.
By normal service I mean that form should start getting all the events. What I have done so far is that on TextBox's KeyDown event; when Escape key is pressed, I have set the focus to the main form like this:
this.Focus(); //where this is mainform.
But this doesn't seem to work since Textbox still keeps receiving all the keys. I have a KeyDown event handler both for Form and Textbox and I have checked that all the KeyDown events pass on to the TextBox. I have a TextBox Leave event Handler as well which never gets called.
This TextBox is the only control on the form and the main form is used for drawing shapes (if that matters).
So, how can I make this TextBox lose focus when user clicks outside of it.
if it works like in VB, for what I remember, try to set the form property KeyPreview to false so all keys will be passed only to the focused control on the form.
If you set your form KeyPreview property to true, your form has first chance to handle any keystrokes that you make. If it is something you want to handle i.e. escape as in your comment above, handle it in your form's KeyDownEvent and mark it as handled so your textbox will not see it.
From above Msdn Page:
When this property is set to true, the form will receive all KeyPress, KeyDown, and KeyUp events. After the form's event handlers have completed processing the keystroke, the keystroke is then assigned to the control with focus.
I guess back in '11 this didn't work, but now
this.ActiveControl = null;
works fine. However if you intend to use Tab to cycle controls, focusing a label with suitable TabIndex is the way.

Suppress Automatic Textbox Selection on Windows Forms Form.Show()

I have an application where I am trying to mimic the "soft description" textboxes like those found for the tags and title locations on this site.
The way I've done this is essentially to create my textbox, and depending on what happens when the mouse pointer enters or leaves the control, it updates the content of the textbox to get the effect.
The problem is what when my form is first shown, the mouse cursor immediately jumps into the first textbox, which removes the title telling the user what the textbox is for.
If I turn off AcceptTab on the textbox, then everything works as expected, but the user loses the ability to tab into the textbox.
Is there a way to turn off this automatic selection of the textbox?
Could you this.Focus() on the form itself, or on some label control?
Bit late but a perfect solution is to select the form on load of form.
Adding this line to the constructor will give the expecting result.
this.Select();
But while using multi thread controls like OpenFileDialog if u want to unfocus/deselect text-box this.Select() was not working so I selected a button in the form using.
button1.Select();
The TabIndex property controls what order things will tab in, and on load, focus goes to the first control (ordered by TabIndex) that has AcceptTab as true. You can change the ordering so that the control that you want the user focus to start in is lowest (and have tabs work cycle through controls as you'd expect).
Alternatively, as Jason suggested, you could simply call Focus() on whatever control or the form itself in the FormLoad event.
I used a variant on Jason's technique. First, I created a dummy textbox with tabindex 0. That way, when the form is shown, that textbox will be selected. Next, I made the dummy textbox have zero width, so that it has no visible component.
However, once the form is loaded, I don't want the user to be able to tab over to the "nonexistant" textbox. Therefore, I added these two bits:
//These functions prevent the textboxes from being implicitly selected.
private void dummyBox_Leave(object sender, EventArgs e)
{
dummyBox.TabStop = false;
}
private void Main_Enter(object sender, EventArgs e)
{
dummyBox.TabStop = true;
dummyBox.Select();
}
Where Main is the name of my form.
Hope this helps someone.
Billy3

Categories