DataVisualization.Charting.Chart PostPaint Event Firing Prematurely - c#

I have a complex chart that I'm drawing and the PostPaint event for System.Windows.Forms.DataVisualization.Charting.Chart seems to be firing prematurely. There is no chart on the screen yet.
Does anyone have a better understanding of the behavior of the PostPaint event with large charts? Is there a better event to listen to? Recommended strategies?
I'm not sure posting code would provide any benefit.

ORIGINAL POST:
So it turns out the answer to this (for me anyway), is to create another thread (I'm doing it with a Task) off of the event. This thread's job is to continually compare the region with an empty image and when it is no longer empty, grab the image and save it in the database. Because it's a thread, this frees up the chart to eventually render itself.
FINAL POST:
In the end, I had to put a lock inside the PostPaint event (it was firing multiple times as TaW indicated it would) and make sure the code inside would only execute a single time (I have a Draw button so these controls get reset every time it's clicked). Additionally, it was necessary for me to create a task to actually do the work of capturing the image and storing it in the database. If I didn't do this, I would get a blank image every time. I did not actually have to check point count or sample the image to see if it was blank.
Locking down the event and creating the task inside the event is what made the difference.

Related

Simple multi-threading issue

I have a class called Movement which moves a picture box (guy on the left) on my form to a random position when it's Lead method gets executed. I also have a method which moves another picture box (dark guy on the right) called SetMrShadowToMove. These two picture boxes are suppose to move at the same time and arrive at the random point (one point for both picture boxes) at the same time.
For now, these methods use a timer to move the picture boxes, but my main intention was to have a loop which runs until the picture box's coordinates meet the random point picked while using Thread.Sleep to delay the process and make an animation of it.
To do that, I need to run both methods on different threads, so my UI thread doesn't get frozen and these methods would run at the same time.
My problem is that I don't know how to run these methods on different threads, and also don't know how to access the picture boxes on the other threads (it seems that this has something to do with invoking and stuff!).
What is the best way to solve this problem?
The best way (in my opinion) is by using a background worker.
those things can do there calculations in the background. If you you want to update the interface after that you can use there report progress event to invoke your main (interface) thread and redraw the screen. You can also the work complete even if you want to have a event of the background worker as a final even (for example if mister shadow is 'destroyed' or something).
I don't know your code of mister shadow so I don't have any direct example code for you. But a full example about how to use a background worker can be found on msdn here. I hope this will help you.

How to decrese the time Holding event occurs?

I want the Holding event occur quicker, by default it takes around 2 seconds to occur:
<Grid Holding="Grid_Holding">
</Grid>
Couldn't find a solution in the documentation. I think I need to change states somehow in Blend!
How to decrese the time holding event occurs? thanks.
It doesn't seem you can change this time threshold! It should be, at max, a user setting (not an application setting). According to the Reference here, this is what define the Holding event:
The Tapped, DoubleTapped, and RightTapped events occur only after the touch point is removed. But the initial Holding event occurs while the touch point is still in contact. The event occurs if the touch point remains in approximately the same PointerPoint position for a period of time. The exact timing of what the system interprets as a holding action is adjustable by users through system settings.
http://msdn.microsoft.com/en-US/library/windows/apps/windows.ui.xaml.uielement.holding.aspx
Also, from the same reference:
Tapped and Holding are mutually exclusive. If the action passes the time threshold to be considered a Hold action, it's not considered to be a Tap action also.
Wouldn't you prefer to subscribe to Tap event instead, or maybe both?
So you would monitor when it happens fast and slow.
http://msdn.microsoft.com/en-US/library/windows/apps/windows.ui.xaml.uielement.tapped.aspx

How to refresh PictureBox

I've little question to ask.
Let's say I've written an ellipse on pictureBox, then clicked a button. I want pictureBox to refresh itself.
I've tried PictureBox.Invalidate(), but could'nt made it.
My best regards...
Try the method PictureBox.Refresh() (inherited from Control).
Have you tried PictureBox.Update(); ? Or try something like this http://msdn.microsoft.com/en-us/library/system.windows.forms.picturebox.image.aspx
There are a couple ways to update the PictureBox, and the method you use makes a difference if you have some lag. I had a program that drew typed characters in a PictureBox, and the keystroke processing was slow so when I typed fast it would lag.
If I pictureBox.Refresh(); after each keystroke, then that refreshes the picture immediately after the keystroke is processed, no matter what. This way, when I typed fast I could see the PictureBox trying to catch up with me as it drew each character.
If instead I pictureBox.Invalidate();, then that refreshes the picture too, but only when the system has some free time. This way, when I typed fast I saw nothing happening while the system tried to catch up, and then everything I'd typed suddenly appeared.
Usually Refresh is better, but here's an article that describes a couple situations where Invalidate is the better choice.

Undo Changes with collection of images

I'm trying to create a undo functionality to a picture box by saving the image right before the paint take place into a array or something. I tried with List but i get the same image all the time, with Image List the size is to small for my porpoises. What are the best practices for saving undo data or how can i store images into memory right before every paint take place? Thank you !
You have to clone the image contents every time. I think you are adding always the reference of the image to the list.
If you want to get undo functionality done properly have a look at the Command Pattern.
Another way would be to calculate the difference of the original image and the image after the operation and then store the difference to save memory.
Many paints will take place on the same image. Windows fires the Paint event whenever part of the control needs to be repainted. Like when you drag another window across the PB. Or minimize and restore the form.
In other words, Paint doesn't tell you that the image changed. You'll need to derive your own class from PictureBox and override the Image property. The setter will be called when the image is changed.

Animate a e.Graphics.DrawLine with arrowhead

I need to "animate" an arrow. It can go in any direction (up, down, left, right and diagonals) and the arrowhead will be at the end. It needs to appear as if it is growing from orgin to the end.
To make matters more complicated it has to be in a user control so it is possible to add to the controls collection in the forms and remove it to delete it from the screen, and its background is really transparent (no color.transparent) so i can't paint the background to "clear" the previous line.
I have it static already (drawn from origin to end) but i can't animate it. I tried to add a timer in the user control but I fail to get a correct algorithm to calculate the intermediate ends of the line while it is growing.
Any help would be appreciated.
Thanks
When using animation on a Windows form you have to use another thread. Look into using a background worker: http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
You don't need another thread - I have succesfully implemented Windows Forms animation.
My design:
Use a Windows.System.Forms.Timer object to call a callback function 'Animate()' at regular intervals
the Animate() function updates a property of your arrow, and then calls Invalidate() on the windows control
this all happens in the same UI thread, so yuo will not get any flicker effects (as long as your control has double duffering switched on).

Categories

Resources