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 |