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.
Related
I m developing a window optimization application in C#. In that Project I have tablelayout panel. And i added pictureboxes to all cells. In application the user can add columns and rows at run-time.
But when the user dynamically add column or row, the application begins to slow down.
My question is with using panel instead of pictureboxes will speed up? (Panel backround image property do same job) Or it doesn't change anything?
I have already set double buffered proterty to true.
I have tablelayout panel. And i added pictureboxes to all cells.
If I understand you correctly, this won't work in WinForms. Here all controls are actual Windows windows, with OS-level handles and all the message pumping logic that entails. Plus the table layout triggers resizing in every single window under it, putting more pressure on it all.
Either go the less lazy route of drawing it all yourself in a memory bitmap and put it in a PictureBox to display, or use a more modern framework like WPF which doesn't have any of the afore-mentioned limitations. In fact, this is trivial in XAML.
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.
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?
I have a simple System.Windows.Forms.Form.
Based on business requirements, once certain functionality becomes available as a result of some background processing, I am increasing the form's size and opening up a previously hidden area with additional controls (buttons etc). The changes to the form's size are done by a background thread, using BeginInvoke.
All this works fine. However, if the user is dragging around the form on the screen, and coincidentally during this time the method that changes form's size is called, the size change does not become effective (technically, the form changes size, but instantaneously reverts to the previous size).
I am changing the form size by setting the Form.Size property, but have tried other ways like setting Form.ClientSize, and calling Form.SetBounds(). Have also tried out Form.SuspendLayout()/Form.ResumeLayout() and forcing Form.PerformLayout().
Nothing I have tried so far works, and when it is being moved around, the form refuses to change size.
Put code in the Form_LocationChanged event to detect if the previously hidden area is visible (or should be via a bool variable) and resize the form accordingly. Otherwise the ResizeEnd event fires after a move ends, try that.
I'm currently writing an custom control which has to hold child control and have to support scrolling and autorisze.
Autoscrolling is not possible because my control is fully selfpainted an only a part of the control should be scrolled.
Now the the repainting of the Controls is extrem slow, especialy with textbox and buttoncontrols with systempainting. Deactivating systempainting (TextBox.BorderStyle = Borderstyle.Fixed) helps, but the control should also support this. Using SetRedraw and updating the controls afterward doesn't help, because the textbox systemdraw is ignored and the textbox looks ugly. Refreshing my whole control or using `RedrawWindow slows the painting down again.
i also already tried to suspend my control and child controls layout without success.
Does anybody know how to speedup the childcontrol painting like AutoScrolling.
My CustomControl has the Style ControlStyles.AllPaintingInWmPaint | ControlStyles.SupportsTransparentBackColor | ControlStyles.OptimizedDoubleBuffer.
The ChildControl bound is changed on (MyControl)Resize and (ScrollBar)OnValueChanged.
Using a Timer helps a little, but i don't know if this is realy the right solution.
EDIT :
I have found the problem, aufter reactivating SetRedraw and Refresh, OnPaint fires 38 times with 37 Controls. Is the any workaround?
It gets slow with that many controls, 37 of them is just rather a lot. For comparison, Microsoft Outlook uses about 50 windows, you've got 38 for just a control. It gets extra slow because of transparency effects on those controls. The OnPaint() method runs so often to provide the background pixels of the controls. You can't always fix that, a Button for example is going to let its parent draw the background even if it is not transparent. Controls are very convenient but they are not cheap.
Only one way to really get ahead here: stop using so many controls and stop trying to support transparency. Not sure what you use, but a Label for example is especially wasteful. Using TextRenderer.DrawText in your OnPaint method also can draw a label, minus the cost of a Control.
I was able to speed it up, by adding a custom flag which tells me if the OnPaint is fired by my control or by a child control. If my control fires the event i draw my controls content to a bitmap and just blit it for the childcontrols.