DateTimePicker locks program when used

I am using a picker to get a DateTime to pass into a function.
The only way this does not lock up is to show the value in a MessageBox before it is used.
I am using VS2013

private void dtpResults_ValueChanged(object sender, EventArgs e)
        {
            DateTime temp = dtpResults.Value;    
            MessageBox.Show(temp.ToLongDateString());
            List<MeetingDetails> meetings = raceDay.GetPastMeetings(temp, false);
            foreach (MeetingDetails meeting in meetings)
            {
               //Do stuff
            }     
        }

Open in new window


Works but

private void dtpResults_ValueChanged(object sender, EventArgs e)
        {
            DateTime temp = dtpResults.Value;    
            List<MeetingDetails> meetings = raceDay.GetPastMeetings(temp, false);
            foreach (MeetingDetails meeting in meetings)
            {
                //Do Stuff
            }
           
        }

Open in new window


Locks up when I try to even see the value of temp before GetPastMeetings is called.

Is there some sort of initailisation I am missing?
I have tried casting value to a DateTime but this makes no difference.
LVL 1
jetbetAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
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.

it_saigeDeveloperCommented:
Have you tried using a DateTime.TryParse(); e.g. -
private void dtpResults_ValueChanged(object sender, EventArgs e)
{
	DateTime temp = DateTime.MinValue;
	if (DateTime.TryParse(dtpResults.Value, out temp))
	{
		List<MeetingDetails> meetings = raceDay.GetPastMeetings(temp, false);
		foreach (MeetingDetails meeting in meetings)
		{
			// Do stuff
		}
	}
}

Open in new window


-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
jetbetAuthor Commented:
DateTime temp = DateTime.MinValue;
            if (DateTime.TryParse(dtpResults.Value, out temp))
            {

Open in new window


Doesn't compile as the first parameter needs to be a string

DateTime temp = DateTime.MinValue;
            if (DateTime.TryParse(dtpResults.Value.ToString(), out temp))
            {    
                List<MeetingDetails> meetings = raceDay.GetPastMeetings(temp, false);

Open in new window


Has the same problem as the original one.
0
it_saigeDeveloperCommented:
What does GetPastMeetings expect (I assume it is a datetime value and a boolean value), but does it expect anything spectacular with regards to this date time value?  Are you noticing the issue when entering in the date time value (via keyboard) or selecting the value (via mouse and calendar dropdown)?

-saige-
0
Learn SQL Server Core 2016

This course will introduce you to SQL Server Core 2016, as well as teach you about SSMS, data tools, installation, server configuration, using Management Studio, and writing and executing queries.

jetbetAuthor Commented:
I am Clicking on the DateTimePicker and selecting a date. The code is triggered as the Value changes.
dtpResults_ValueChanged(object sender, EventArgs e)

GetPastMeetings expects a DateTime object and a Boolean but the issue is before this.
If I put a breakpoint on the line
List<MeetingDetails> meetings = raceDay.GetPastMeetings(temp, false);
and then hover or click on temp or meeting the program locks (waiting type circle appears) and I cannot even close it with the DEBUG-> Stop Debugging menu item, as the IDE locks up, but need to shut the program (not IDE) via the task manager.
0
it_saigeDeveloperCommented:
What happens if you surround it with a try...catch???
private void dtpResults_ValueChanged(object sender, EventArgs e)
{
	try
	{
		DateTime temp = DateTime.MinValue;
		if (DateTime.TryParse(dtpResults.Value.ToString(), out temp))
		{
			List<MeetingDetails> meetings = raceDay.GetPastMeetings(temp, false);
			foreach (MeetingDetails meeting in meetings)
			{
				// Do stuff
			}
		}
	}
	catch (Exception ex)
	{
		MessageBox.Show(string.Format("{0} - {1} [{2}]", ex.Source, ex, ex.Message), "Exception Reported");
	}
}

Open in new window

-saige-
0
Jacques Bourgeois (James Burger)PresidentCommented:
I would stop looking for casting issues. If this was the problem, you would also have it with your MessageBox, since it does not make any change to the value, it simply display it.

If you do not have more use for temp than what we see here, you do not really need it. Try GetPastMeetings(dtpResults.Value, false). I have seen a few strange situations where passing a property instead of a variable, or the reverse, corrected a problem that did not seem to make any sense.

Another thing to try.

If you set a breakpoint on the line that calls GetPastMeetings, and continue from the breakpoint, does it work.

When things work when you pause (with your MessageBox or a breakpoint) but do not work in real time, it is very often some kind of synchronization problem with something else working in the background.

Application.DoEvents often corrects these types of problems, by letting the application finish most of the background operations before going on.

If not, then a call to Threading.Thread.Sleep can add a controlled delay before GetPastMeetings. The problem with Sleep is that it is hard to determine the most efficient delay. You cannot just test on one one computer and assume it will work everywhere. The background operations can take longer to run on less efficient computers, so it is always good to add 50% to 100% to what you think is a proper delay.
0
jetbetAuthor Commented:
if I use
catch (Exception ex)
            {
                String message = ex.Message;
            }

Open in new window


it is caught but if I try to see ex.Message by hovering over it the program locks up as before

If I use
catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                String message = ex.Message;
            }

Open in new window


I get that "Object reference not set to an instance of an object" in the message box
0
it_saigeDeveloperCommented:
I know what you are dealing with.  Why the messagebox makes any difference is beyond me.  ValueChanged is getting called while the datetimepicker is still being initialized.  So what I would recommend is this.

Create a boolean variable to let you know when the form has been initialized/loaded.  Set the initialized/loaded variable to true in the constructor of the form (after the InitializeComponent call).  Finally surround the logic in your ValueChanged Event with a check on the boolean value; e.g. -
using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace EE_Q28671659
{
	public partial class Form1 : Form
	{
		bool fIsLoaded = false;

		public Form1()
		{
			InitializeComponent();
			fIsLoaded = true;
		}

		private void dtpResults_ValueChanged(object sender, EventArgs e)
		{
			if (fIsLoaded)
			{
				DateTime temp = dtpResults.Value;
				List<MeetingDetails> meetings = raceDay.GetPastMeetings(temp, false);
				foreach (MeetingDetails meeting in meetings)
				{
					//Do stuff
				}
			}
		}
	}
}

Open in new window

-saige-
0
it_saigeDeveloperCommented:
You could also do a null check on the value in case you don't want to use a boolean check; e.g. -
using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace EE_Q28671659
{
	public partial class Form1 : Form
	{
		public Form1()
		{
			InitializeComponent();
		}

		private void dtpResults_ValueChanged(object sender, EventArgs e)
		{
			if (dtpResults != null && dtpResults.Value != null)
			{
				DateTime temp = dtpResults.Value;
				List<MeetingDetails> meetings = raceDay.GetPastMeetings(temp, false);
				foreach (MeetingDetails meeting in meetings)
				{
					//Do stuff
				}
			}
		}
	}
}

Open in new window

-saige-
0
jetbetAuthor Commented:
This also causes the issue

private void dtpResults_ValueChanged(object sender, EventArgs e)
        {
            if (fIsLoaded)
            {
                Application.DoEvents();
                Thread.Sleep(2000);
                String value = "bob";
                String value2 = value;
            }
}

Open in new window


A Breakpoint on the value2 line also causes the same behaviour so there must be some corruption in the picker object.
Another developer here has the same issue.
0
jetbetAuthor Commented:
Code is now working without a MessageBox.
I have added a label called laPastDate and set this with the value (instead of using a message box).
            private void dtpResults_ValueChanged(object sender, EventArgs e)
        {

            try
            {
                DateTime temp = DateTime.MinValue;
                if (DateTime.TryParse(dtpResults.Value.ToString(), out temp))
                {
                    laPastDate.Text = temp.ToShortDateString();

                    List<MeetingDetails> meetings = raceDay.GetPastMeetings(temp, false);
                    if (meetings != null)
                    {
                        LV_PastMeeting.Items.Clear();
                        foreach (MeetingDetails meeting in meetings)
                        {
                            ListViewItem meetItem = new ListViewItem(meeting.number);
                            meetItem.SubItems.Add(meeting.name);
                            meetItem.Tag = meeting;
                            LV_PastMeeting.Items.Add(meetItem);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                String message = ex.Message;
            }
        }

Open in new window


I have no idea why such a hack works, but it does.
0
it_saigeDeveloperCommented:
Interesting...  Let me do some testing...

-saige-
0
it_saigeDeveloperCommented:
I created a naked project with just the datetimepicker and a textbox with no additional logic and cannot reproduce your issue...

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

namespace EE_Q28671659
{
	public partial class Form1 : Form
	{
		public Form1()
		{
			InitializeComponent();
		}

		private void OnValueChanged(object sender, EventArgs e)
		{
			textBox1.Text = dateTimePicker1.Value.ToShortDateString();
		}
	}
}

Open in new window

Form1.Designer.cs -
namespace EE_Q28671659
{
	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.dateTimePicker1 = new System.Windows.Forms.DateTimePicker();
			this.textBox1 = new System.Windows.Forms.TextBox();
			this.SuspendLayout();
			// 
			// dateTimePicker1
			// 
			this.dateTimePicker1.Location = new System.Drawing.Point(13, 13);
			this.dateTimePicker1.Name = "dateTimePicker1";
			this.dateTimePicker1.Size = new System.Drawing.Size(200, 20);
			this.dateTimePicker1.TabIndex = 0;
			this.dateTimePicker1.ValueChanged += new System.EventHandler(this.OnValueChanged);
			// 
			// textBox1
			// 
			this.textBox1.Location = new System.Drawing.Point(13, 40);
			this.textBox1.Name = "textBox1";
			this.textBox1.Size = new System.Drawing.Size(200, 20);
			this.textBox1.TabIndex = 1;
			// 
			// Form1
			// 
			this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
			this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
			this.ClientSize = new System.Drawing.Size(284, 264);
			this.Controls.Add(this.textBox1);
			this.Controls.Add(this.dateTimePicker1);
			this.Name = "Form1";
			this.Text = "Form1";
			this.ResumeLayout(false);
			this.PerformLayout();

		}

		#endregion

		private System.Windows.Forms.DateTimePicker dateTimePicker1;
		private System.Windows.Forms.TextBox textBox1;
	}
}

Open in new window

-saige-
0
jetbetAuthor Commented:
The thing is you are using a GUI component for the display which is how I got it working.

All the examples I have seen do things along this way rather than using the DateTime value for something other than display.
0
it_saigeDeveloperCommented:
I saw your follow-up and used a method to generate the same value.  Let me try creating an object and doing something with the value.

-saige-
0
it_saigeDeveloperCommented:
I still cannot reproduce the error.  I can set the value to an object property and manipulate it without issue; e.g. -
using System;
using System.Windows.Forms;

namespace EE_Q28671659
{
	public partial class Form1 : Form
	{
		public Form1()
		{
			InitializeComponent();
		}

		private void OnValueChanged(object sender, EventArgs e)
		{
			Data test = new Data() { Date = dateTimePicker1.Value };
			test.Date = test.Date.AddHours(5);
			textBox1.Text = test.Date.ToString();
		}

		private string GetDate(DateTime value)
		{
			return Convert.ToString(value);
		}
	}

	class Data
	{
		public DateTime Date { get; set; }

		public DateTime GetAdjustedDate(int Hours)
		{
			return Date.AddHours(Hours);
		}
	}
}

Open in new window

-saige-
0
jetbetAuthor Commented:
I have now commented out the label code and it is still working even after a clean and rebuild.
I am stumped. Thanks for your help.

I believe the TryParse code helped so will award you the points based on that.
0
Jacques Bourgeois (James Burger)PresidentCommented:
Philosophical rampage, if you are interested and if you permit.

"I am stumped (that it now works)" in computing is something that gives me the creeps. "I believe" that something that has not been proven is the case does the same. How can you believe that something you commented out solved the problem?

This might seem unimportant, but in this field, one has to learn to think straight. Intuition, specially combined with experience, has a lot to do with programming. But coming to conclusions on beliefs only is never a good thing. You learn nothing in programming if you rely on beliefs instead of facts.

If you are lucky, the comments, which were not there in your original code, simply seemed to solve the problem because the compiler did not interpret the code exactly as it did before. It might appear stupid at first sight, but extra lines or extra empty spaces sometimes bring a compiler to do things differently. In all possibilities, the comments might have solved your problem more than the TryParse did  (emphasis on the might, no belief here).

If you are not so lucky, it might be that some background process that slowed down your computer before is not currently running. If so, the problem might reappear later. It might also appear on another computer that is slower than yours, because everything that has been said up to now points to a background process.

Solving a problem without knowing why what we did solved it is always a dangerous thing. Oh! The blood has stopped coming out. I don't know what I did, but the problem is solved, we are OK! It simply transformed into internal bleeding, which is worse.

My interpretation (once again, not a belief) is that adding the TryParse and the Label simply slowed down things, the same way that the Application.DoEvents or Sleep suggested sooner would have done.

One always to be careful about saying that an approach is better than another, but somebody who is reading your code later (maybe yourself) won't understand what you are doing today. Why the heck is he storing that value in a Label? doesn't it already show in the DateTimePicker? What was I thinking when I took a property that is a datetime, converted it to string, and then used TryParse to check if it was a datetime? Is the mother of a son the mother of that son? Any programmer whose worth 10 cents would scratch his head trying to understand what that code with the TryParse and the Label is doing.

You turned left 3 times, which puts you in the same direction that turning right once would have done.

DoEvents and Sleep are self commenting and clearly indicate what your intention is, because this is the aim of these methods. DoEvents ever more so, because it is very often an indication that you have no control over what is happening in the background and simply let every ongoing event finish before going on. This would solve the problem suggested by somebody else: "ValueChanged is getting called while the datetimepicker is still being initialized". DoEvents is made expressly for these situations. Uselessly using a TryParse and a Label is no indication that you needed to slow down or wait.

I do not say that DoEvents and TryParse would have solved your problem. This is a kind of problem that is hard to replicate. Other experts were not able to replicate it... because they are not in the same application, they are not in the same environment, and everything, even the solution that worked, points to a problem coming from the specific application or environment. You are the only one that can solve it.

But for the sake of your users, try to make sure that you did. Beliefs can define what you do on Saturday or Sunday, and being stumped by a good surprise can make someone happy. But they have nothing to do with good programming.
0
jetbetAuthor Commented:
All fair comments.

I actually did try the doEvents and Sleep but that did not solve my problem at the time.
I also do not like to be stumped by anything and will be investigating further in my own time.

I should have been more verbose with my comment but due to the time pressure of multiple concurrent projects was pushed for time. This is a poor excuse.

I agree this was not helpful for other programmers looking at this question and so am happy you pointed this out.
0
Jacques Bourgeois (James Burger)PresidentCommented:
I am always glad to meet programmers who can think and not simply react. I am thus glad that you appreciated my comments.

I am also very aware of the constraints of everyday programming, where finding a solution, any solution, is the only thing that counts... at the moment. I just thought that it was important to point out that ideally, we should go a little further.
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.