C# datetime validation problem

We have a Visual Studio 2010, C#, Windows application.

We have a custom form in the C# project which has a datetime control.
We are capturing the Validating event for this control.

The event appears to get fired correctly when the user attempts to leave the control.

If the user uses the mouse to select a new date, when inside the validation routine, the Value property is set to the newly selected value.

However, if the user uses the keyboard to enter a new date, when inside the validation routine, the Value property is still set to the previous value.

How do I get the Value property to have the correct value after the user changes the value with the keyboard? Or, what is the correct way to get the new value when inside the Validating event for the datetime control?

Thanks.
LVL 1
msambhuAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

plusone3055Commented:
can you post the validation method ?
0
msambhuAuthor Commented:
Sure. I've been able to recreate this in a new Windows project.
The validation snippet from the test project:

private void dtReqShipDate_Validating(object sender, CancelEventArgs e)
{
      this.lblValidateValue.Text = this.dtReqShipDate.Value.ToString("M/d/yyyy");
}
0
plusone3055Commented:
are you firing this method when you click a button ?

please post the whole routine so I can see whats going on please
0
Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

msambhuAuthor Commented:
That is the whole method from my test project.

But, more info...
Inside the InitializeComponent() method:
this.dtReqShipDate.Validating += new System.ComponentModel.CancelEventHandler(this.dtReqShipDate_Validating);

I've updated a zip file of the test form I used to recreate the issue.
WinTest.zip
0
it_saigeDeveloperCommented:
I cannot reproduce the problem using the files from your zip.  Is there something else that needs to occur.

What I tried:

Modified the date using the keyboard and tabbed out of the control.  Label updates with new value.
Modified the date using the keyboard and moused out of the control.  Label updates with new value.
Modified the date using the date dropdown and tabbed out of the control.  Label updates with new value.
Modified the date using the date dropdown and moused out of the control.  Label updates with new value.

-saige-
0
msambhuAuthor Commented:
We've since discovered that this happens when only 1 of the date items is updated.

So...
Use mouse to click into the date field.
Use keyboard to update the default date from 3/4/2015 to 3/5/2015. Only update the 4 to a 5, do not update the month or year.
Use mouse to set focus to the other text box.

Could there be some problem with my installation of VS2010?
0
it_saigeDeveloperCommented:
Let me try your steps to see if I can reproduce.  Also, how many date time inputs are you using?

-saige-
0
it_saigeDeveloperCommented:
Just tried your steps.  Did not reproduce the same error.  Is it possible that you have multiple Date Time Inputs using the same validate method?

To test use the following for your validate method:
private void dtReqShipDate_Validating(object sender, CancelEventArgs e)
{
	if (sender as Control != dtReqShipDate)
		MessageBox.Show("Called from {0}", (sender as Control).Name);
	lblValidateValue.Text = dtReqShipDate.Value.ToString("M/d/yyyy");
}

Open in new window

-saige-
0
msambhuAuthor Commented:
IT_SAGE- I added your suggested snippet into my test project. I still get the same behavior. No prompt about it getting called from another object.

I now suspect that there is something wacky with my installation of VS2010. Or, maybe not.

The guy sitting next to me just tried my test form and is able to recreate the behavior.

It happens if we click into the field and change the month or date with the keyboard (using the number keys, not the arrow keys.) Using the arrow keys results in correct behavior. Changing the year works correctly as well.
0
it_saigeDeveloperCommented:
Are you using the number pad keys or the number keys from the top row?

-saige-
0
it_saigeDeveloperCommented:
Ok, I *finally* was able to reproduce your issue using the number row keys and the number pad keys.  Let me do some debugging.

-saige-
0
msambhuAuthor Commented:
Yes... using the number row keys.
This laptop does not have a number pad.
0
it_saigeDeveloperCommented:
Ok, more information on the bug.  It fabricates itself when you use only a 1-digit entry for day, month or year.  Using a custom date formatter does not alter this behaviour.  As a fix, you can either, use the ValueChanged Event or force a value changed by using the Leave Event; e.g. -

Form1.cs -
using System.ComponentModel;
using System.Windows.Forms;

namespace EE_Q28629329
{
	public partial class Form1 : Form
	{
		bool IsSendingKeys = false;

		public Form1()
		{
			InitializeComponent();
		}

		private void OnValidating(object sender, CancelEventArgs e)
		{
			lblValidateValue.Text = dtReqShipDate.Value.ToString("M/d/yyyy");
		}

		private void OnLeave(object sender, System.EventArgs e)
		{
			if (sender is DateTimePicker)
			{
				DateTimePicker dtp = sender as DateTimePicker;
				if (dtp != null && !string.IsNullOrEmpty(dtp.Text))
				{
					try
					{
						IsSendingKeys = true;
						SendKeys.SendWait("{RIGHT}");
						SendKeys.SendWait("{LEFT}");
					}
					finally
					{
						IsSendingKeys = false;
					}
				}
			}
		}
	}
}

Open in new window

Form1.Designer.cs -
namespace EE_Q28629329
{
	partial class Form1
	{
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.IContainer components = null;

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
		protected override void Dispose(bool disposing)
		{
			if (disposing && (components != null))
			{
				components.Dispose();
			}
			base.Dispose(disposing);
		}

		#region Windows Form Designer generated code

		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.dtReqShipDate = new System.Windows.Forms.DateTimePicker();
			this.textBox1 = new System.Windows.Forms.TextBox();
			this.lblValidateValue = new System.Windows.Forms.Label();
			this.SuspendLayout();
			// 
			// dtReqShipDate
			// 
			this.dtReqShipDate.CustomFormat = "";
			this.dtReqShipDate.Format = System.Windows.Forms.DateTimePickerFormat.Short;
			this.dtReqShipDate.Location = new System.Drawing.Point(69, 57);
			this.dtReqShipDate.Name = "dtReqShipDate";
			this.dtReqShipDate.Size = new System.Drawing.Size(95, 20);
			this.dtReqShipDate.TabIndex = 1;
			this.dtReqShipDate.Leave += new System.EventHandler(this.OnLeave);
			this.dtReqShipDate.Validating += new System.ComponentModel.CancelEventHandler(this.OnValidating);
			// 
			// textBox1
			// 
			this.textBox1.Location = new System.Drawing.Point(41, 31);
			this.textBox1.Name = "textBox1";
			this.textBox1.Size = new System.Drawing.Size(100, 20);
			this.textBox1.TabIndex = 0;
			// 
			// lblValidateValue
			// 
			this.lblValidateValue.AutoSize = true;
			this.lblValidateValue.Location = new System.Drawing.Point(202, 64);
			this.lblValidateValue.Name = "lblValidateValue";
			this.lblValidateValue.Size = new System.Drawing.Size(35, 13);
			this.lblValidateValue.TabIndex = 2;
			this.lblValidateValue.Text = "label1";
			// 
			// Form1
			// 
			this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
			this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
			this.ClientSize = new System.Drawing.Size(462, 246);
			this.Controls.Add(this.lblValidateValue);
			this.Controls.Add(this.textBox1);
			this.Controls.Add(this.dtReqShipDate);
			this.Name = "Form1";
			this.Text = "Form1";
			this.ResumeLayout(false);
			this.PerformLayout();

		}

		#endregion

		private System.Windows.Forms.DateTimePicker dtReqShipDate;
		private System.Windows.Forms.TextBox textBox1;
		private System.Windows.Forms.Label lblValidateValue;
	}
}

Open in new window


This resolution is discussed here:  https://social.msdn.microsoft.com/forums/vstudio/en-US/e2f6bf92-a61f-440f-83e0-8ce3b5e7ba9d/datetimepicker-bug-for-date-with-single-digit

Personally I do not know if Microsoft has gotten word of this bug or if they are even going to resolve it.

-saige-
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
msambhuAuthor Commented:
Great. I'll check it out later today.
Thanks.
0
msambhuAuthor Commented:
I really hate having to use hacks like this.
But, it works great. Thanks.
0
it_saigeDeveloperCommented:
Agreed.

-saige-
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.