I have a datetimepicker in C#. When I click on it, it expands to show a monthly calendar, when I click the left arrow to go back a month, it changes the value and calls my event. The event includes too much code to include here but it calls several functions needless to say.
The problem I'm having is that when I click that left arrow it gets stuck in some sort of loop and keeps descending through the months and I can't stop it. One of the functions that is being called contains a Application.DoEvents() and if I comment that out it doesn't get stuck in the loop, but I need that command to update another section of the interface. Any idea why this is happening?
I can duplicate it sometimes with this code, sometimes it just does it a couple times, sometimes it gets stuck in the loop.
private void DateTimePickerValueChangedEvent(object sender, EventArgs e)
{
afunction();
}
private void afunction()
{
listView1.Clear();
panel1.Visible = true;
Application.DoEvents();
}
I also have the same problem. In my case, instead of calling DoEvents I'm updating a Crystal Report view. The only workaround I found is to update my view upon the CloseUp event instead of ValueChanged or TextChanged.
Scott, how did you finally corrected your problem ?
The DateTimePicker ValueChanged event is buggy. Per Microsoft Windows Forms Team on this page https://connect.microsoft.com/VisualStudio/feedback/details/1290685/debugging-datetimepicker-event-hangs-vs:
"The DateTimePicker control installs a mouse hook as part of its functionality, but when the debugger has the WinForms application stopped on a breakpoint, it allows the possibility of a deadlock if VS happens to get a mouse message. For now, the deadlock is unfortunately a consequence of the DateTimePicker's design. The mouse hook is installed when the drop down is clicked to display the calendar. This means that breakpoints should not be sent in any event handlers which would be called while the calendar is active. We are currently investigating whether it is possible to address this issue and we will update this thread with further information if we are able to make a fix available."
Without seeing any of the code, try these steps:
Comment out the entire event handler
to see how fast it runs with nothing
attached to it.
Uncomment lines one at a time to see
which ones are causing the most
problems.
Analyze those method calls.
...
Profit!
You could try a couple of things. Get rid of the DoEvents inside of the ChangedEvent.
Call the doevents inside of a seperate function after maybe a period of time (thread.sleep() ?).
I know doevents does cause issues but I rarely use it.
event procedure ValueChanged :
set parameter in sender.tag
enableTimer and execute parameter using sender.tag
example:
private void DateTimePicker_ValueChanged(object sender, EventArgs e)
{
DateTimePicker ThisSender = (DateTimePicker)sender;
Timer.Tag = ThisSender.Name.ToString() + "=" + ThisSender.Value;
Timer.Enabled = true;
}
Related
I am implementing Custom Task Panes with E-Mail Messages in Outlook.
The core is taken from this link MSDN (Walkthrough: Displaying Custom Task Panes with E-Mail Messages in Outlook)
Handler for property change is added:
void TaskPane_VisibleChanged(object sender, EventArgs e)
{
Globals.Ribbons[inspector].ManageTaskPaneRibbon
.toggleButton1.Checked = taskPane.Visible;
...some code here...
mailItem.PropertyChange += PropertyChangeHandler;
}
PropertyChangeHandler checks is recipients have changed and does some heavy routine with posts and so on. But... If I add 10 recipients and start to remove them with backspace PropertyChangeHandler stops firing at some point.
No errors. Buttons on custom task pane work fine.
What is wrong?
Seems that either event is eaten or inspector is incorrect, but I cannot spot problem and find the solution.
I also think that it might be about "heavy load" when next event is fired before previous is completed, but this is a guess
You need to call the Save method or save the message explicitly to make the PropertyChange event fired. Outlook caches values in the UI and doesn't propagate changes until the item is saved.
Also I'd suggest creating a log file (a regular text file) where you can write the debug statements. Thus, you will understand what happens in the code.
I have a problem with DateTimePicker, which was quite easy to reproduce, and feels like a bug in the control itself, but I wanted to make sure I'm not misinterpreting anything.
First, code for this is really simple, create a WinForms application with a DateTimePicker (Our project is in .net 4.0, but I tried creating it in .net 4.5, same problem). The picker itself has Custom format with "HH:mm" as format, and also ShowUpDown set to true.
It has a validation method as follows:
private void dateTimePicker1_Validating(object sender, CancelEventArgs e)
{
dateTimePicker1.Value = DateTime.Now;
}
Set a breakpoint on that row.
Make sure to have another control in the application so that you can tab out of the DateTimePicker to trigger validation.
Now, when in the program navigate your way to the DateTimePicker and enter something "202" in for example the hour-field. This will have it look like you have written 20 first, and when you write the second "2", it will be just the 2 in the field for now.
Now tab out of the DateTimePicker. This will trigger the validation breakpoint. Note how the value of the DateTimePicker now is a date set to 20 for hours. Let the line execute and watch the value of the DateTimePicker again. Now the value os 02 for hours instead (NOT(!!) the value of DateTime.Now)
So, somehow after setting the value to DateTime.Now, it changes value to what the previous unfinished value entered in the DateTimePicker.
How come it is like this, is there any way I can work around this?
I cannot repro this. The Windows version matters a great deal, lots of common control quirks got fixed in later releases. I'm on Windows 8.
It is however a common problem, these controls are picky about what you do to them when they fire an event. They tend to have code in them that runs after they fired the event which may well invalidate what you did. The Validating event is especially tricky because it is raised as a side-effect of the focus changing. If the DTP didn't yet get that same notification then there's trouble. Pretty typical event ordering trouble. Do favor the Leave event if you are not actually using Validating to validate the data.
Sounds like a match. A general solution to these kind of ordering problems is to run your code after the event has fired and code execution is no longer inside the control's code. You can do so elegantly with the form's BeginInvoke() method. The target runs after your program re-enters the message loop and the UI is back into a quiescent state. Like this:
private void dateTimePicker1_Validating(object sender, CancelEventArgs e) {
this.BeginInvoke(new Action(() => dateTimePicker1.Value = DateTime.Now));
}
During the Validating event, I see the behaviour explained by you, but once the validating event is completed, the value is set to DateTime.Now.
Assuming that you want it to set the value of the DateTimepicker control to DateTime.Now during the Validating event itself, I found that setting the value twice shows the value changed to DateTime.Now -
dateTimePicker1.Value = DateTime.Now;
dateTimePicker1.Value = DateTime.Now;
I have a button with an event handler attached to it; 2-clicking it in the designer takes me to the code. Nowhere is the handler being unhooked/detached.
Some code I expected to run apparently isn't, so I put a bunch of MessageBox.Show()s in the handler, even at the very beginning, but none of them display (Note: I can't step through the code; I have to do it this way (arggghhhh)).
Here's some of the code:
private void btnFind_Click(object sender, System.EventArgs e) // Find and list Records
{
MessageBox.Show("Made it into btnFind_Click 0"); //TODO: Remove after debugging
try
{
if (barcodeScanner != null)
{
// Turn off the listening
barcodeScanner.BarcodeScan -= new BarcodeScanner.BarcodeScanEventHandler(barcodeScanner_BarcodeScan);
}
MessageBox.Show("Made it into btnFind_Click 1"); //TODO: Remove after debugging . . .
What could be preventing this code from being executed?
UPDATE
Based on Mike C's idea, I added a MessageBox to the button_close handler. And when I click it, it does fire, but only after other code runs first; in this case, that other code doesn't prevent the Close_Click from (eventually) firing; with the Find button, though, it completely preempts it...IOW, I see the message from the Close button at the end when I click it, but I never see any of the messages in the Find button handler when I click it...
UPDATE 2
Oh my lanta/say it ain't so, Joe! What's happening is an event is being kicked off in the form's overloaded constructor, and somehow this event is always fired just then (after clicking the find button). The message I'm seeing, that preempts everything in the button event handler, takes place in a method which is called by processBarcode() which is called by processBarcode1(), which is invoked from barcodeScanner_BarcodeScan1(), which is called by barcodeScanner_BarcodeScan(), which is set up in frmEntry's overloaded constructor. If the previous coder had intended to drive me insane, he couldn't have done much better.
I guess there's a reason there's so much maintenance work "out there" or "out here": because there's so much bad broken code AND because the cats who make such a mess scratch a bunch of sand on it and walk away.
And this code is chock full of "huh?!?##$%^?!?" moments, where bizarre gyrations are not commented on at all, and yet there is this comment:
// Check connection
checkConnection();
The problem could be that the Click event of the button is not subscribed to properly. If there is no line resembling
this.btnFind.Click += new System.EventHandler(this.btnFind_Click);
in the Designer file of the form, that's it.
I am a new C# user and now I have encountered a problem in using BindingNavigator.
I am using bindingNavigator to update records in a table of database. Before I leave current updated record and enter the next record by clicking Next button, I will perform some validation, if there is any thing incorrect, I hope it could raise a warning to give me chance to correct the wrong fields instead of moving to the next record.
I added some lines in bindingNavigatorMoveNextItem_MouseDown event, but it still move to next item even there are some thing wrong with current record(fields have some logical connection). Can any expert here help me out about that? Many Thanks!
You have two approaches: either overriding WndProc and prevent mouse click window message from calling the base's WndProc, or simply overriding OnMouseClick:
class Hello : BindingNavigator
{
private bool canFire = false;
protected override void OnMouseClick(MouseEventArgs e) // second approach
{
// don't call base method so that event doesn't fire up
if (this.canFire)
base.OnMouseClick(e);
}
}
I know this is old.. but for anyone else...
You should use the normal buttons, and just use the validating event, canceling if anything fails your validation.
The control does not display the property in the designer, but you can still set it : bindingnavigator.CausesValidation = true;
I do this in the form load.
this alone still won't do it.
you also need to set the focus.
bindingnavigator.focus();
I do this in the bindingnavigator_ItemClicked event so it happens no matter what button is clicked.
I have a C# windows forms application. The way I currently have it set up, when Form1_Load() runs it checks for recovered unsaved data and if it finds some it prompts the user if they want to open that data. When the program runs it works alright but the message box is shown right away and the main program form (Form1) does not show until after the user clicks yes or no. I would like the Form1 to pop up first and then the message box prompt.
Now to get around this problem before I have created a timer in my Form, started the timer in the Form1_Load() method, and then performed the check and user prompt in the first Timer Tick Event. This technique solves the problem but is seems like there might be a better way.
Do you guys have any better ideas?
Edit: I think I have also used a background worker to do something similar. It just seems kinda goofy to go through all the trouble of invoking the method to back to the form thread and all that crap just to have it delayed a couple milliseconds!
I would use Form1_Shown()
Use the Shown event. It seems to suit what you need, and will only display the first time the form is shown.
Form f1 = new Form();
f1.Shown += new EventHandler(f1_Shown);
public void f1_Shown(object sender, EventArgs e)
{
// Show dialog in here
}
Try the "Shown" event:
Form.Show Event
Using a Windows.Forms.Timer is a good, stable, well-known, and easily understood technique for doing what you want. I would avoid any other timer objects.
The form's Shown event works well.
Overload / override the Show method. (My preferred technique for greater control.) In this method, I would do the checking needed. When ready, I would call the base.Show method, then do any other processing, such as message boxes, prompts, logging, or whatever.