Windows Develop Bookmark and Share   
 index > Windows Forms General > SuspendLayout and Layout Event on a UserControl
 

SuspendLayout and Layout Event on a UserControl

Hi!

Is there any way to force Layout event to be fired? Here is what I have in mind:

I have a UserControl which has a number of custom properties. Each time the value of a property changes thishas impact on some controlsadded on the custom control.To improve peformanceI want these modifications to be suspended when SuspendLayout was executed for the control. So I thought that the proper thing to do is to add the code that applies property modificationsin the Layout event.

What is left to do is force this event every time a property changes and let the framework decide whether to fire the Layout event or wait since SuspendLayout was executed.

Is this right? If so how can I fire the Layout event only when SuspendLayout was not previously executed?

papadi  Thursday, May 25, 2006 1:08 PM

Papadi,

Use the PerformLayout() method to force OnLayout.You can pass the control itself as the affected control and the property name or use PerformLayout() directly.

Karthik Krishnaswami  Friday, May 26, 2006 7:35 AM
You should call the base's OnLayout method. If you're not overriding a concrete control, you have to make sure you're deriving from Control (or a derivative of Control) to get at that method.
Peter Ritchie  Thursday, May 25, 2006 3:24 PM
BTW, you can tell if you're between SuspendLayout and ResumeLayout.
Peter Ritchie  Thursday, May 25, 2006 3:25 PM
Control.Refresh() or Control.Invalidate()
JRQ  Thursday, May 25, 2006 7:06 PM

JRQ wrote:
Control.Refresh() or Control.Invalidate()

Hi JRQ,

I have tries both but none of them forces the Layout event.

papadi  Friday, May 26, 2006 6:54 AM

Peter Ritchie wrote:
You should call the base's OnLayout method. If you're not overriding a concrete control, you have to make sure you're deriving from Control (or a derivative of Control) to get at that method.

Hi Peter,

I discovered the OnLayout method just after posting my question. However, OnLayout method fires the Layout event event if suspendlayout was executed. Isn't this weird!?

papadi  Friday, May 26, 2006 6:56 AM

Peter Ritchie wrote:
BTW, you can tell if you're between SuspendLayout and ResumeLayout.

This is exactly what I need Peter! How is this possible?

papadi  Friday, May 26, 2006 6:57 AM

Papadi,

Use the PerformLayout() method to force OnLayout.You can pass the control itself as the affected control and the property name or use PerformLayout() directly.

Karthik Krishnaswami  Friday, May 26, 2006 7:35 AM
Sorry, that should have been "you can't tell", my mistake. My fingers don't listen to my brain sometimes.
Peter Ritchie  Friday, May 26, 2006 2:11 PM

Hello again!

I decided to dig this thread up since I discovered something strange. I finally used PerformLayout to force the Layout event. If SuspendLayout was executed in the meanwhile the PerformLayout is suspended and Layout event is fired when ResumeLayout is executed. It turns out that this is what I wanted to do.

I have a problem with the follownig scenario:

SuspendLayout is executed
PropertyA is changed and this fires the PerformLayout(me, "PropertyA") command
PropertyB is changed and this fires the PerformLayout(me, "PropertyB") command
ResumeLayout is executed

This scenario will fire the Layout event once (fine so far!) but... the AffectedProperty will have "PropertyA" as its value. I would expect the event not to have any value in AffectedProperty parameter so that I can update all properties in the event. Isn't this right?

papadi  Thursday, July 27, 2006 6:42 AM
papadi wrote:

Hello again!

I decided to dig this thread up since I discovered something strange. I finally used PerformLayout to force the Layout event. If SuspendLayout was executed in the meanwhile the PerformLayout is suspended and Layout event is fired when ResumeLayout is executed. It turns out that this is what I wanted to do.

I have a problem with the follownig scenario:

SuspendLayout is executed
PropertyA is changed and this fires the PerformLayout(me, "PropertyA") command
PropertyB is changed and this fires the PerformLayout(me, "PropertyB") command
ResumeLayout is executed

This scenario will fire the Layout event once (fine so far!) but... the AffectedProperty will have "PropertyA" as its value. I would expect the event not to have any value in AffectedProperty parameter so that I can update all properties in the event. Isn't this right?

The default layout engine for controls other than TableLayoutPanel only caches the last PerformLayout request.

Peter Ritchie  Thursday, July 27, 2006 2:46 PM

Hi Peter,

if so, then the AffectedProperty parameter of the Layout event has no use. Since you are not able to tell which properties where affected the code should pretend that all of them did. Right?

Here is my workaround:

I created my only collection of affected properties and replaced following call:

PerformLayout(me, "PropertyName")

with

myCollection.Add("PropertyName")
PerformLayout()

Then is use this collection to see what was updated and clear it at the end of the Layout event.

papadi  Thursday, July 27, 2006 2:52 PM
papadi wrote:
if so, then the AffectedProperty parameter of the Layout event has no use. Since you are not able to tell which properties where affected the code should pretend that all of them did. Right?
I agree. I think the LayoutEngine class is flawed. The LayoutEngine actually has an internal virtual method called ProcessSuspendedLayoutEventArgs that is called if layout is suspended. LayoutEngine.ProcessSuspendedLayoutEventArgs does nothing, and the default layout engine used by controls does not override that. Because this virtual is internal it can't be seen outside of the system assembly and can't be overridden (and furthermore has a parameter whose type is also internal to system assembly...).

papadi wrote:
Here is my workaround:

I created my only collection of affected properties and replaced following call:

PerformLayout(me, "PropertyName")

with

myCollection.Add("PropertyName")
PerformLayout()

Then is use this collection to see what was updated and clear it at the end of the Layout event.

I assume you're removing the calls to SuspendLayout() and ResumeLayout()--which would seem to be useless at this point?

Peter Ritchie  Thursday, July 27, 2006 3:01 PM
No, I' not. SuspendLayout will not allow Layout event to be executed. In the meanwhile my collection will collect all properties that have been changed. When ResultLayout is called and Layout event is fired, the code there will check the collection, update UI that uses the contained properties and clear the collection.
papadi  Thursday, July 27, 2006 6:03 PM

You can use google to search for other answers

Custom Search

More Threads

• Resource Files + .CS Files associations
• Differences between mshtml.HTMLDocument and System.Windows.Forms.HTMLDocument
• yellow line around button while mouseover
• Unable to cast object of type 'ControlCollection' to type 'ControlCollection'.
• [SOLVED]Forms and Menory usage
• Adding the code in Timer Tick event.
• When i maximize a form the contents in it are not maximized
• Keyboard Focus
• Detecting Dirty Data in local DataTables
• Combo Box Question!