DateTimePicker valueChanged is too slow

Adagio

Well-known member
Joined
Dec 12, 2005
Messages
162
Programming Experience
Beginner
In my DTP when the user presses Enter I have set it to call some code that uses the DTP value, but unfortunately the DTP updates it's value too slow (the code is called before the value has changed). This causes the code to use the old value instead of the new value

If I make it open a msgbox inside the valueChanged code, then the value changes before the other code is called, but that's not really an option


Is there a way to make sure that the value is set (if there has been made a change) before the other code is called?
 
hide a textbox behind the DTP and then call your code on Textbox TextChanged?

I.E.
VB.NET:
Expand Collapse Copy
Private Sub DateTimePicker1_TextChanged......
 
me.textbox1.text = me.dateTimePicker1.text
 
End Sub
 
 
Private Sub TextBox1_TextChanged......
 
'Put your code here!
 
End Sub
 
In my DTP when the user presses Enter I have set it to call some code that uses the DTP value, but unfortunately the DTP updates it's value too slow (the code is called before the value has changed). This causes the code to use the old value instead of the new value

If I make it open a msgbox inside the valueChanged code, then the value changes before the other code is called, but that's not really an option


Is there a way to make sure that the value is set (if there has been made a change) before the other code is called?

Please post the code youre using..

Ideally you should attach to the ValueChanged of the DTP.. because it doesnt fire until the value has changed.

Its not that DTP changes its value slowly, it's that the DTP.KeyXXX event can/does occur before valuechanged..

Basically, it sounds like youre attached to the wrong event.. post the code and we'll take a look
 
Incidentally, I'm aware of the other DTP thread you had going, about (basically) trying to reprogram the user to not use the tab key to move on from DTP... My comment on programming peons such as ourselves, trying to change the established institution that is "The Way Windows Works(TM)" is a very dumb idea. Aside from the fact that users the world over see a control they recognise and expect it to work in a certain way (deviation = bad hci = lame programmer), you must also consider that Microsoft have spent millions of dollars more than you have on the R&D of a good user interface; Accept that their way is right, if not for that it is defacto, but for that they have put more resources than some countries will ever own, into its development.


The simplest solution I can think of for your problem is to do both what VBNewb, John and yourself have suggested..

Have a tickbox that when enabled, shows DateTimePickers that behave NORMALLY. Each of these DTP, in their value changed events, send the YYYYMMDD date into a Masked textbox, hidden exactly behind the DTP.
Code it so that upon textbox value change, your action happens..

Advanced users can toggle the checkbox, which sets all the DTP to hidden and the textboxes to shown. Now they can type into the boxes to rapidly enter info.. Because it is the textbox value changed that does something, everyone is happy.

User -> DTP -> Masked Text -> Action
User -> Masked Text -> Action
 
hide a textbox behind the DTP and then call your code on Textbox TextChanged?

I can't, as the event shouldn't fire every time the value changes, it should only fire when the Enter key is pressed (or when the user clicks on a button)

Please post the code youre using..

There's really nothing in the code of interest. It's just when the user presses Enter it calls the sub getInterneAfvg(). And there's no extra code fired when the valueChanged event fires (only during testing I included a msgbox in the event sub)

VB.NET:
Expand Collapse Copy
Private Sub dteFromDateInterneAfvigelser_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles dteFromDateInterneAfvigelser.KeyDown
    If e.KeyCode = Keys.Enter Then
         getInterneAfvg()
    End If
End Sub
 
mhh, but theres a basic usability issue here.. why must you fire the event off when the user presses enter? what is so critical about this datebox that as soon as the user has finished with it, it must be used?
 
mhh, but theres a basic usability issue here.. why must you fire the event off when the user presses enter? what is so critical about this datebox that as soon as the user has finished with it, it must be used?

Pressing enter is to make it more user friendly. Instead of forcing the user the use the mouse (or use tab to set focus, then press enter) to click on the "get data" button. Kinda the same as in a browser when the user writes the address in the address box, it wouldn't make sense to force the user to press the "go" button to load the page
And the reason the value in the DTP is important is that the data it needs to find in the database depends on the value of the DTP
 
I do something similar on my app when searching for dates, but click the "search" button instead.

I still have a hidden textbox behind the dtp....

Why can't you (theoretically)

(a) Select a date from the DTP
(b) Upon pressing Enter within the DTP;
(c) textbox.text = DTP.text
(d) call your "fill" code, using the parameter not as the DTP but as the textbox text

...That's how I'd do it. Instead of the DTP being slow, it sounds more like your parameter from the DTP isn't set correctly..
 
VB.NET:
Expand Collapse Copy
[SIZE=2][COLOR=#0000ff]Private[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Sub[/COLOR][/SIZE][SIZE=2] dtpDateRequested_KeyPress([/SIZE][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][SIZE=2] sender [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Object[/COLOR][/SIZE][SIZE=2], [/SIZE][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][SIZE=2] e [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] System.Windows.Forms.KeyPressEventArgs) [/SIZE][SIZE=2][COLOR=#0000ff]Handles[/COLOR][/SIZE][SIZE=2] dtpDateRequested.KeyPress[/SIZE]

[SIZE=2]If e.KeyCode = Keys.Enter Then[/SIZE]
 
[SIZE=2]me.tableadapter.fillbydate(me.dataset.datatable, me.lbldaterequested.text)[/SIZE]
 
[SIZE=2]End If[/SIZE]
[SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Sub[/COLOR][/SIZE]

 
[SIZE=2][COLOR=#0000ff]Private[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Sub[/COLOR][/SIZE][SIZE=2] dtpDateRequested_ValueChanged([/SIZE][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][SIZE=2] sender [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] System.Object, [/SIZE][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][SIZE=2] e [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] System.EventArgs) [/SIZE][SIZE=2][COLOR=#0000ff]Handles[/COLOR][/SIZE][SIZE=2] dtpDateRequested.ValueChanged[/SIZE]
[SIZE=2][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=2].lblDateRequested.Text = [/SIZE][SIZE=2][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=2].dtpDateRequested.Text[/SIZE]
[SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Sub[/COLOR][/SIZE]
 
Oi yoi yoi! What a catastrophe! First of all, do you want the code to be called before or after the value is changed? And what value do you want to use when Enter is pressed (don't forget they can use the Return key as well)? Your first post is unclear.

A DTP is a selection of sorts and it is WEIRD to press Enter inside it! Make them use the mouse and the popup calendar. That way they're already using the mouse so they wont mind clicking a button as well.

You shouldn't really use a whole textbox to store a value unless you actually use that textbox's event handlers or display the text inside it. You should use an intermediary variable instead - much less overhead (not like it matters on modern PC's but that's not the point).

Please just explain what it is you want because depending on what it is the answer changes greatly. I've done similar stuff with DTP's in the past and they're a nuisance. Half the time I just get rid of the calendar and force them to use the little arrows. My only response at this stage is set some temprary variable (not so much a textbox) to the value. Then when your method is called you first evaluate the value and if it passes you run the method. For the best out of us: write what you want point by point so we can understand.
 
Pressing enter is to make it more user friendly. Instead of forcing the user the use the mouse (or use tab to set focus, then press enter) to click on the "get data" button. Kinda the same as in a browser when the user writes the address in the address box, it wouldn't make sense to force the user to press the "go" button to load the page
And the reason the value in the DTP is important is that the data it needs to find in the database depends on the value of the DTP

Yes, but the info I'm trying to drag out of you, one fingernail at a time, is WHY DO YOU WANT THE DTP TO BE SO INSTANT?

What do you care if the ValueChanged event fires 10 times during the edit of the control? What is so precious about this dtp that it must fire once, when the user says so? What does this DTP do? What is it used for? What do you do when the user pressed enter? How many times can I ask this same question... :D
 
Yes, but the info I'm trying to drag out of you, one fingernail at a time, is WHY DO YOU WANT THE DTP TO BE SO INSTANT?

What do you care if the ValueChanged event fires 10 times during the edit of the control? What is so precious about this dtp that it must fire once, when the user says so? What does this DTP do? What is it used for? What do you do when the user pressed enter? How many times can I ask this same question... :D

Didn't I just answer that in my last post? :confused:
The date in the DTP is needed to get data out of the database (as in "SELECT ... WHERE FldDate >= #'date from DTP'#")

Oi yoi yoi! What a catastrophe! First of all, do you want the code to be called before or after the value is changed? And what value do you want to use when Enter is pressed (don't forget they can use the Return key as well)? Your first post is unclear.

The value I need is the one that is actually written in the DTP (what is visible to the user), so the code should be called after the value has changed, not before as it does now

A DTP is a selection of sorts and it is WEIRD to press Enter inside it! Make them use the mouse and the popup calendar. That way they're already using the mouse so they wont mind clicking a button as well.


I would really HATE being forced to use the mouse for something like that
 
Didn't I just answer that in my last post? :confused:
No, you didnt. I re-read what you wrote and , yeah OK, i can understand that you "want to get some data out of a database depending on what the user types" - i write apps that work like that all the time..

The date in the DTP is needed to get data out of the database (as in "SELECT ... WHERE FldDate >= #'date from DTP'#")

Why do you have to get the data out of the database as soon as the user is sure they have finished setting the date? What is the mandate that, 0.01 seconds after the user makes the 8th keypress of typing a date, the database is queried?

The value I need is the one that is actually written in the DTP (what is visible to the user), so the code should be called after the value has changed, not before as it does now
THat's what the valuechanged event is for.. You see, value changed uses English in the "Past Tense" --> changed. It occurs after the value has changed.
 
Why do you have to get the data out of the database as soon as the user is sure they have finished setting the date? What is the mandate that, 0.01 seconds after the user makes the 8th keypress of typing a date, the database is queried?

I'll see if I can explain it a different way, because it seems like you have no idea what I'm talking about

The database is not queried as soon as the user has finished writing the date, but as soon as the user presses enter
Let's make an example: if the user is standing in the month field presses 1 (as in January) and "Enter" just after, the data the user gets from the database is wrong as the database query is using the old value from the DTP, because the value of the DTP changes AFTER the keypressed event has been fired

Currently the only way to fix this problem is by doing this:

VB.NET:
Expand Collapse Copy
Private enterKeyPressed As Boolean = False

    Private Sub dteFromDate_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles dteFromDate.KeyDown

        If e.KeyCode = Keys.Enter Then
            enterKeyPressed = True
        End If
    End Sub

    Private Sub dteFromDate_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles dteFromDate.ValueChanged
        If enterKeyPressed = True Then
            getLotsOfWeirdDataFromDatabaseUsingTheCorrectDate()
            enterKeyPressed = False
        End If
    End Sub


But this only works IF the user has changed the date, but if the user just 'stands' in the DTP and presses Enter, then nothing happens as the valueChanged event never gets fired
 
Okay, call me crazy but pressing Enter in a DTP does NOTHING to the value. So regardless of when Enter is pressed the value will remain the same. So it doesn't make any difference whether the value changed event gets called or not. Just call the method in the KeyPress event. Test this if you wish and MsgBox it all you like, but as far as I can tell, the value will not change when Enter is pressed. Thus the value will always be the 'right' value when Enter is pressed. If you want to make sure that the value has changed since the last Enter press then have an if statement comparing the current value to the old value (stored in a temp variable) whenever Enter is pressed. If the values are the same then don't do anything otherwise call the method.

If that isn't what you're looking for I give up.
 
Back
Top