I have a WinForms form containing many controls. On resizing the form, I need to place and resize the components and redrawing pictures in PictureBoxes.
I had problems with flickering, so now I call SuspendLayout at the beginning of the SizeChanged event (and ResumeLayout at the end).
But it was not enough, so I use a boolean variable indicating, if the form should be repainted. I set it to true at SizeChanged event and false after the Paint event. This solved the problem, because for some mysterious reason the Paint event was raised incredibly often.
The form still did not repaint correctly sometimes. I solved that by calling SizeChanged method in ResizeEnd event (and I don't know why it worked).
Now almost everything works, but after maximizing/unmaximizing the form, the pictures in the PictureBoxes are not repainted. Everything is sized and placed right, except for the pictures, which have the same size (but the PictureBoxes are resized). I have no idea why or what else I can do (except for disabling maximizing).
I would appreciate any advice.
Related
I have a PictureBox control on my form for which I have written two events for MouseEnter and MouseLeave. On MouseEnter anther PictureBox enters the form and stands beside the original and with MouseLeave the second PictureBox goes way.
All works fine. Except when the cursor is on the original PictureBox’s border area the MouseEnter and MouseLeave events are repeatedly run. So the second image enters and leaves the form until the cursor is taken away. This makes a strange sight.
How can I avoid this situation?
The border area can be tricky, especially when you want to trigger something the might influence it even if it is only by a few pixels..
One classic situation is when you want to resize or move a control by clicking an dragging it at its border. Unless you use the internal calls and simply code mouseenter, -leave, -move, -down and -up you may well end up with e.g. moving the control away from the mouse and thereby triggering another leave event.
This often occurs only at one set of borders, like left&top or right&bottom.
You need to check you code for any such influences, like the new PictureBox pushing the old one away by a few pixels or a resize that makes it smaller; even one pixel can lead to the effect you see..
If the MouseEnter event is triggering a border to be drawn, or the size of the first PictureBox to change in any way, that can cause the effect you describe.
You could add a check against the mouse coordinates in MouseEnter to ensure that the mouse pointer gets far enough into the control's interior before the event fires. That would prevent an instant firing of the Leave event.
I have a control on my app that can be resized by the user, it has some button anchored to the top-right side and also a scrollbar.
The problem is that when the control is resized, the controls anchored to the right also changes the position, and only after a few ms the controls goes into the right place. So it looks like the child controls "shakes" while the parent control is resized.
I already tried all kind of things, like using SuspendLayout and ResumeLayout on the parent control, setting double buffering and other styles on each control to true, setting WS_EX_COMPOSITED bit, but nothing seems to make this issue go away.
This issue is present on other apps too, and is pretty annoying.
So is there anyway to fix that on .net?
Maybe making it render everything to a backbuffer, and then when everything is finished render it to screen?
I would create a new event that fires after resize is done, using a little timer magic stopping and starting a timer with an interval about 50ish ms on each resize event you can create this fake ResizeEnd kind of event.
On the first resize event I would stop the drawing of the UI using the dllimport call (dont recall which it was) to stop drawing the contents of your window or control. Then when the resize is done, enable drawing again using the same dllimport call.
The effect would be that it will only redraw itself after resize is done or every 50ms if you pause while resizing.
ResizeEnd: WinForms - action after resize event
SuspendDrawing: How do I suspend painting for a control and its children?
override the below virtual method from namespace using System.Drawing;
protected override Point ScrollToControl(Control activeControl)
{
return AutoScrollPosition;
}
should solve the problem !
In our application, all the cells of rows are user controls which got initialized while paint
if you scroll many times or maximize /minimize, it tried to redraw cells, row wise and handle count peeks and application crashes.
question here: when I scroll a bit, for every row , it calls onpaint() but rows which are now moved out of view,(only 20 rows visible in maximized window) how can they be disposed ?
UI constructor called once, when you load but after that only paint got triggered.
Consider a Grid with every cell as user controls. If I maximize/minimize the window or scroll the grid, every control gets re initiate causing handle leak though GDI count remains steady.
OnPaint is usually called a lot of times and not under your control. Creating controls within OnPaint is not a good idea therefore. (In your case, there must be a lot of identical controls at the same place, i guess)
Use the form's constructor, the Form.Load event or any user-driven event (click on buttons, menus, toolbars, ...) for creating controls.
I have a problem with panel and weird area on it. I fill my panel with many PictureBoxes 32x32px, and a small area of this panel is filled with white area.
Here is how it looks like:
You can see that the first PictureBox has specified grass image, which is 32x32px, but the PictureBox below has only half of it's image. It's very strange.
I have also an onClick event specified for PictureBoxes to change it's background to other image. If I click on 'working' PictureBox it's background changes, but when I click on 'corrupted' one, it doesn't.
So basically, my question is - what could be the reason for such effect? Is it possible to find it out without analysing a code? I would like to avoid putting a code here, because it's very complicated and long.
EDIT
I used WinSpy++ and it is the result (red point is a place where i hover cursor)
so we can see that PictureBox is partly hidden behind this white area.
I don't know if the question is still active, but I'll try to respond anyway. It is more a comment on it, but since I'm not allowed to make comments yet I'll just answer.
I had encountered a similar issue when implementing some picutreBox drawing using onPaint event handler. The problem was that I called pictureBox.Invalidate() during onPaint and it caused displaying of the unwanted white color box. You might want to avoid using Invalidate() or Refresh() in your onPaint event if there is one.
If this is not the case it might also help to refresh the form or pictureBoxes that are corrupted. Try to call this.Refresh() after the form initialization, preferably in onLoad or onShown event handler.
If it still doesn't help then the problem is somewhere else, I'd guess there is a control hidden somewhere that causes that. But we'll need to see some code in order to suggest any other advice.
I am sure many developers are frustrated by the flickering when resize events happens faster than onPaint event.
I have created many user objects that is shown on the main form.
When I try to set the location and size of each controls at the resize event of the main form, I get the flickering.
To resolve this I wanted to do a new approach as mentioned below.
When resizeBegin event is triggered, show a borderline of current frame
When resize event is triggered, only the borderline will be resized leaving the controls in the main frame untouched.
The tricky part is when the borderline is larger than original size, I want it to show the background of the window as it self.
Click for Enlarge image
On the contrary if the borderline is smaller then, I still want the original objects to be shown
Click for Reduce image
When resizeEnd then the borderline will be hidden and the controls in the frame will be resized.
Does anybody know how to implement the tricky part mentioned at resize?