Situation: A C# Windows Forms application with a TextBox and a ComboBox. AutoValidate is set to EnableAllowFocusChange.
The TextBox represents and is shown as a percentage value e.g. "10 %" which is stored as an int. Both input controls are data bound, the TextBox with a parsing and formatting ConvertEventHandler as well as a Validating CancelEventHandler.
When entering an invalid input like "abc" and leaving the control: My Validation is performed and fails (e.Cancel = true, ErrorProvider ..). And my parsing fails (e.Value stays "abc").
Problem: When I now change the value of the ComboBox and leave it (lost focus/perform validation) or do a ValidateChildren, my format function is called with the last valid percentage value and the wrong input is lost.
Stacktrace: The problem is triggered by a ReportPropertyChanged of the ComboBox and leads to Binding.PushData, FormatObject and OnFormat -> Which calls my format function with the original value.
I want my TextBox to stay invalid and no magical reset. What can I do to prevent a value reset? Or what did I do wrong?
Thanks!
Related
In my Windows Form Application, I want to implement a feature where the user has to fill in the serial number of a product that is when matched with any product in the database, the product must appear in a grid. I want to do so using textbox textChanged event.
I am confused in figuring out that either I must prevent firing the textChanged event before the textbox value matches any value in the database. Is there any way to make the textbox expect a specific amount of text or number (my serial numbers are going to be fixed length - like 10001, 10002, 10003) before running the remaining code for showing product in the grid?
You can use TextLength property of the TextBox to get length of text. For example:
private void textBox1_TextChanged(object sender, EventArgs e)
{
if (textBox1.TextLength < 5)
return;
//Send query to database
}
Note: As it's also mentioned by Jimi in the comments, it's good idea to set MaxLength of TextBox to prevent entering more text.
Consider the use of a [MaskedTextBox][1]. A MaskedTextBox is similar to a standard TextBox, except you define the format of the input text. This can be anything, letters, numbers, dashes, etc.
In your case you accept only input of five digits.
Use the windows forms designer to add a MaskedTextBox, or add one yourself:
this.maskedTextBox1 = new System.Windows.Forms.MaskedTextBox();
this.maskedTextBox1.Location = ...
this.maskedTextBox1.Size = ...
// etc. Advise: let forms designer do this
// accept only input of five digits:
this.Mask = "00000";
The operator sees an indication of the length of the requested input. It is impossible for the operator to type a non-digit. Event when all five digits are entered, but also while typing (TextChanged), so if desired you can implement autocompletion. You can even get notified if operator presses one invalid key, so you can inform the operator about the error
In c# Winforms, I have a textbox which is databound to a DateTime column in my database.
When I type in something like the following into the textbox
05/12/1977
Once the textbox loses focus, the first 0 is removed so that it says
5/12/1977.
The reason this is a problem is because I actually want to use masked textbox so the /'s are already in the textbox for the user. But once the 0 is removed, the date gets messed up like so
51/21/977_
The date still saves correctly but this causes some of my form validation to not react properly since it views the masked textbox as not being completed. Anyone know of a way to prevent that first 0 from being removed?
Thanks!
This is just a problem with culture info. Since my textbox was databinded to a DateTime variable, all I had to do was change the method in which DateTime's are displayed as strings. The following code in my constructor of my GUI form fixed the problem
var culture = CultureInfo.CurrentCulture.Clone() as CultureInfo;
culture.DateTimeFormat.ShortDatePattern = "MM/dd/yyyy";
System.Threading.Thread.CurrentThread.CurrentCulture = culture;
I have a basic app which contains a gridview with a sqldatasource. The datasource includes two date parameters. The params are linked to two textboxes which are prepopulated but can be modified by the user for their desired date range. I have two validation controls on each textbox. A requiredfieldvalidator and a comparefieldvalidator. The latter being a check for a valid date format.
When I (intentionally) break one of the dates, say, by adding a letter e.g 19/03/2014a (I'm in the U.K, date format is dd/mm/yy) the validation kicks in perfectly and it returns a message to say the date is invalid.
The issue:
Now at this point if I immediately select a row on the gridview, the app derails and I get an error: "Conversion failed when converting datetime from character string" This is expected given that I am using the dates in the textboxes as parameters for my gridview datasource and one of them now contains an invalid date. In an attempt to prevent the SelectedIndexChanged firing at all I have tried to handle the SelectedIndexChanging event for the gridview and cancel the row select. Here is the code for that:
protected void GridView1_SelectedIndexChanging(object sender, GridViewSelectEventArgs e)
{
Page.Validate();
if (!Page.IsValid)
{
e.Cancel = true;
return;
}
}
This codes "works" in that it prevents the SelectedIndexChanged event and also the gridview databind, BUT, I still get the same error: "Conversion failed when converting datetime from character string".
Can someone assist me with this please?
Help much appreciated as ever!
kind regards
Paul.
EDIT: Well I tried the suggestion of a regular expression. I removed other validators(both required and compare) The same error arises. No change.
What I don't understand is that when I cancel the the gridview selected index change event in "GridView1_SelectedIndexChanging" and the "GridView1_SelectedIndexChanged" does not fire, I would expect then that the page would be returned unchanged. But it totally derails and brings up the error. Why?! I'm cancelling the action!
When I step through the code with the invalid date entered, I can see that the gridview is not being databound there. Is it possibly attempting to DataBind() anyway?
Help appreciated greatly!
regards
Paul
EDIT: I finally solved this myself. I disabled automatic databinding and called DataBind() myself at the appropriate times. Another measure I thought of was to add validation login in the T-SQL so that invalid dates did not result in querying the db. There is likely to be a better solution but I couldn't find it and no one suggested it.
Removed Required field validator and go with Regular expression validator where you specify the regular expression of date and validate page against it.
Right now with required field validator its not firing validation because textbox has value but its not checking whether textbox has valid date or not.
See Regex to validate date format dd/mm/yyyy
I want a TextBox in Listview DataTemplate, which is bound to an int or double property takes 0 or 0.0 automatically when it is made empty i.e. when the whole text of the TextBox is deleted.
You could put in value converters which convert empty strings to 0/0.0 in ConvertBack. After the binding propagates back to the source the binding engine usually fetches the value again so you should end up with that as the Text.
I have a databound DateTimePicker:
dateDateTimePicker.DataBindings.Add(new Binding("Value", paymentBindingSource, "Date", true);
paymentBindingSource.DataSource = payment;
payment is Entity Framework object. payment.Date contains valid DateTime. When form is shown, dateDateTimePicker contains correct value, but an ErrorProvider is shown next to it, saying "Value of '01.01.0001 00:00:00' is not valid for 'Value'." It disappears when I change dateDateTimePicker value to anything.
Try reversing those two lines of code. The first line is probably looking to the data source, which, at that point, is null.
Would it be possible to see your validation code? I am guessing the validation error occurs when you first load the form, and that the way you bind the data does not clear the (existing) validation error, while when you manually change the value, that is triggering the relevant code.