custom control size

  • Thread starter Thread starter cronusf
  • Start date Start date
C

cronusf

I have a custom control that draws a special grid. The size of the
control should be computed based on the number of rows and columns
(plus some padding). Right now I set the Width and Height of the
control manually in OnPaint() (based on the number of rows/columns).
This is working, but I am just wondering if this is the recommended
way.
 
Hi,

You should try to limit the size adjustments to whenever it is necessary.
Doing it in the paint event is not optimal as you would adjust the size
potentially far more often than necessary, and maybe not enough if there is
no paint event even though the size should have changed.

The control should not adjust its own size at runtime either as you may end
up covering other controls placed on the parent control.

If you need to adjust the size of the control based on the number of
columns/rows present, I would probably calculate the size needed to show
everything when the number of columns/rows is known, then possibly pass an
event with this information and have the parent adjust the size, if it wants
to.
 
There is indeed an override; OnSizeChanged, that should be used in this
case.

--
--
Bob Powell [MVP]
Visual C#, System.Drawing

Ramuseco Limited .NET consulting
http://www.ramuseco.com

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.


Morten Wennevik said:
Hi,

You should try to limit the size adjustments to whenever it is necessary.
Doing it in the paint event is not optimal as you would adjust the size
potentially far more often than necessary, and maybe not enough if there
is
no paint event even though the size should have changed.

The control should not adjust its own size at runtime either as you may
end
up covering other controls placed on the parent control.

If you need to adjust the size of the control based on the number of
columns/rows present, I would probably calculate the size needed to show
everything when the number of columns/rows is known, then possibly pass an
event with this information and have the parent adjust the size, if it
wants
to.

--
Happy Coding!
Morten Wennevik [C# MVP]


I have a custom control that draws a special grid. The size of the
control should be computed based on the number of rows and columns
(plus some padding). Right now I set the Width and Height of the
control manually in OnPaint() (based on the number of rows/columns).
This is working, but I am just wondering if this is the recommended
way.
 
Jeff Johnson said:
What's the point of the OnSizeChanged? All it does is raise the Resize event
and then call any delegates which have been wired to the SizeChanged event.
But OnResize also calls delegates that are wired to the Resize. So why
two...?

Actually, that is not all it does. You can override the OnSizeChanged
method to trap SizeChanged events fired elsewhere.

protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);

// Additional code needed to run when the size changes
}
 
Actually, that is not all it does. You can override the OnSizeChanged
method to trap SizeChanged events fired elsewhere.

protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);

// Additional code needed to run when the size changes
}

I'm still not clear on this. Are there situations when the framework
fires Resize but not SizeChanged?
 
Jack Jackson said:
I'm still not clear on this. Are there situations when the framework
fires Resize but not SizeChanged?

The framework won't ever fire 'Resize' only 'SizeChanged' but SizeChanged
will be fired when a control is resized. To detect a SizeChanged event you
typically subscribe to the SizeChanged event or override the OnSizeChanged
method (The reason for 'On' before the event name is due to limitations in
inheriting events, as only the base class can fire the actual event.
Inherited classes needs to use a method exposed by the base class).
 
The framework won't ever fire 'Resize' only 'SizeChanged' but SizeChanged
will be fired when a control is resized. To detect a SizeChanged event you
typically subscribe to the SizeChanged event or override the OnSizeChanged
method (The reason for 'On' before the event name is due to limitations in
inheriting events, as only the base class can fire the actual event.
Inherited classes needs to use a method exposed by the base class).

I thought SizeChanged raised the Resize event?

If Resize is only raised from SizeChanged, why is there a Resize
event?

I still don't understand the purpose of Resize.
 
Jack Jackson said:
Jack Jackson said:
On Wed, 9 Apr 2008 00:05:01 -0700, Morten Wennevik [C# MVP]


:


There is indeed an override; OnSizeChanged, that should be used in this
case.

What's the point of the OnSizeChanged? All it does is raise the Resize event
and then call any delegates which have been wired to the SizeChanged event.
But OnResize also calls delegates that are wired to the Resize. So why
two...?


Actually, that is not all it does. You can override the OnSizeChanged
method to trap SizeChanged events fired elsewhere.

protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);

// Additional code needed to run when the size changes
}

I'm still not clear on this. Are there situations when the framework
fires Resize but not SizeChanged?

The framework won't ever fire 'Resize' only 'SizeChanged' but SizeChanged
will be fired when a control is resized. To detect a SizeChanged event you
typically subscribe to the SizeChanged event or override the OnSizeChanged
method (The reason for 'On' before the event name is due to limitations in
inheriting events, as only the base class can fire the actual event.
Inherited classes needs to use a method exposed by the base class).

I thought SizeChanged raised the Resize event?

If Resize is only raised from SizeChanged, why is there a Resize
event?

I still don't understand the purpose of Resize.

My apologies Jack, there is indeed a Resize event, and it is fired after
the SizeChanged event and it is indeed fire in reponse to some code running
in Control.OnSizeChanged.

The sequence when resizing a control is OnResizeBegin -> OnSizeChanged ->
OnResize -> OnSizeEnd

The documentation says that the Resize event is fired when a Control is
resized, whereas the SizeChanged event is fired when the Size property is
changed. It is a little more complicated than this as overriding
OnSizeChanged and NOT pass the event to base.OnSizeChanged() will prevent the
Resize event from firing, so handling SizeChanged instead of Resize to detect
size changes appears to be safer.
 
Jack Jackson said:
:

On Wed, 9 Apr 2008 00:05:01 -0700, Morten Wennevik [C# MVP]


:


There is indeed an override; OnSizeChanged, that should be used in this
case.

What's the point of the OnSizeChanged? All it does is raise the Resize event
and then call any delegates which have been wired to the SizeChanged event.
But OnResize also calls delegates that are wired to the Resize. So why
two...?


Actually, that is not all it does. You can override the OnSizeChanged
method to trap SizeChanged events fired elsewhere.

protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);

// Additional code needed to run when the size changes
}

I'm still not clear on this. Are there situations when the framework
fires Resize but not SizeChanged?


The framework won't ever fire 'Resize' only 'SizeChanged' but SizeChanged
will be fired when a control is resized. To detect a SizeChanged event you
typically subscribe to the SizeChanged event or override the OnSizeChanged
method (The reason for 'On' before the event name is due to limitations in
inheriting events, as only the base class can fire the actual event.
Inherited classes needs to use a method exposed by the base class).

I thought SizeChanged raised the Resize event?

If Resize is only raised from SizeChanged, why is there a Resize
event?

I still don't understand the purpose of Resize.

My apologies Jack, there is indeed a Resize event, and it is fired after
the SizeChanged event and it is indeed fire in reponse to some code running
in Control.OnSizeChanged.

The sequence when resizing a control is OnResizeBegin -> OnSizeChanged ->
OnResize -> OnSizeEnd

The documentation says that the Resize event is fired when a Control is
resized, whereas the SizeChanged event is fired when the Size property is
changed. It is a little more complicated than this as overriding
OnSizeChanged and NOT pass the event to base.OnSizeChanged() will prevent the
Resize event from firing, so handling SizeChanged instead of Resize to detect
size changes appears to be safer.

I guess I still don't understand what OnResize is useful for. If I
understand it correctly, resizing a control (I can't find any
documentation for what "resize" means, but I assume it means changing
the size via the mouse or keyboard, or when the size changes due to
the parent changing when the control is anchored or docked) results
in:

OnResizeBegin
OnSizeChanged
OnResize
OnResizeEnd

while changing the Size property results in:

OnSizeChanged
OnResize

Since it appears that OnSizeChanged and OnResize always occur in pairs
(assuming that OnSizeChanged calls the base class implementation), why
not just have OnSizeChanged?
 
Jack Jackson said:
Jack Jackson said:
On Wed, 9 Apr 2008 11:17:00 -0700, Morten Wennevik [C# MVP]


:

On Wed, 9 Apr 2008 00:05:01 -0700, Morten Wennevik [C# MVP]


:


There is indeed an override; OnSizeChanged, that should be used in this
case.

What's the point of the OnSizeChanged? All it does is raise the Resize event
and then call any delegates which have been wired to the SizeChanged event.
But OnResize also calls delegates that are wired to the Resize. So why
two...?


Actually, that is not all it does. You can override the OnSizeChanged
method to trap SizeChanged events fired elsewhere.

protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);

// Additional code needed to run when the size changes
}

I'm still not clear on this. Are there situations when the framework
fires Resize but not SizeChanged?


The framework won't ever fire 'Resize' only 'SizeChanged' but SizeChanged
will be fired when a control is resized. To detect a SizeChanged event you
typically subscribe to the SizeChanged event or override the OnSizeChanged
method (The reason for 'On' before the event name is due to limitations in
inheriting events, as only the base class can fire the actual event.
Inherited classes needs to use a method exposed by the base class).

I thought SizeChanged raised the Resize event?

If Resize is only raised from SizeChanged, why is there a Resize
event?

I still don't understand the purpose of Resize.

My apologies Jack, there is indeed a Resize event, and it is fired after
the SizeChanged event and it is indeed fire in reponse to some code running
in Control.OnSizeChanged.

The sequence when resizing a control is OnResizeBegin -> OnSizeChanged ->
OnResize -> OnSizeEnd

The documentation says that the Resize event is fired when a Control is
resized, whereas the SizeChanged event is fired when the Size property is
changed. It is a little more complicated than this as overriding
OnSizeChanged and NOT pass the event to base.OnSizeChanged() will prevent the
Resize event from firing, so handling SizeChanged instead of Resize to detect
size changes appears to be safer.

I guess I still don't understand what OnResize is useful for. If I
understand it correctly, resizing a control (I can't find any
documentation for what "resize" means, but I assume it means changing
the size via the mouse or keyboard, or when the size changes due to
the parent changing when the control is anchored or docked) results
in:

OnResizeBegin
OnSizeChanged
OnResize
OnResizeEnd

while changing the Size property results in:

OnSizeChanged
OnResize

Since it appears that OnSizeChanged and OnResize always occur in pairs
(assuming that OnSizeChanged calls the base class implementation), why
not just have OnSizeChanged?

Beats me. After several retries due to some framework source code bug I was
able to find a machine that was able to step into Control.OnSizeChanged using
Visual Studio 2008 and all it does is fire OnResize(EventArgs.Empty) as well
as passing on the SizeChanged event to any subscribers.

If you have access to Visual Studio 2008 and want to see for yourself.
Follow this guideline

[Configuring Visual Studio to Debug .NET Framework Source Code]
http://blogs.msdn.com/sburke/archiv...tudio-to-debug-net-framework-source-code.aspx

There might be historical reasons for keeping the Resize event, or perhaps
the SizeChanged event is not needed, but was created because there was a Size
property.
 
Jack Jackson said:
:

On Wed, 9 Apr 2008 11:17:00 -0700, Morten Wennevik [C# MVP]


:

On Wed, 9 Apr 2008 00:05:01 -0700, Morten Wennevik [C# MVP]


:


There is indeed an override; OnSizeChanged, that should be used in this
case.

What's the point of the OnSizeChanged? All it does is raise the Resize event
and then call any delegates which have been wired to the SizeChanged event.
But OnResize also calls delegates that are wired to the Resize. So why
two...?


Actually, that is not all it does. You can override the OnSizeChanged
method to trap SizeChanged events fired elsewhere.

protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);

// Additional code needed to run when the size changes
}

I'm still not clear on this. Are there situations when the framework
fires Resize but not SizeChanged?


The framework won't ever fire 'Resize' only 'SizeChanged' but SizeChanged
will be fired when a control is resized. To detect a SizeChanged event you
typically subscribe to the SizeChanged event or override the OnSizeChanged
method (The reason for 'On' before the event name is due to limitations in
inheriting events, as only the base class can fire the actual event.
Inherited classes needs to use a method exposed by the base class).

I thought SizeChanged raised the Resize event?

If Resize is only raised from SizeChanged, why is there a Resize
event?

I still don't understand the purpose of Resize.


My apologies Jack, there is indeed a Resize event, and it is fired after
the SizeChanged event and it is indeed fire in reponse to some code running
in Control.OnSizeChanged.

The sequence when resizing a control is OnResizeBegin -> OnSizeChanged ->
OnResize -> OnSizeEnd

The documentation says that the Resize event is fired when a Control is
resized, whereas the SizeChanged event is fired when the Size property is
changed. It is a little more complicated than this as overriding
OnSizeChanged and NOT pass the event to base.OnSizeChanged() will prevent the
Resize event from firing, so handling SizeChanged instead of Resize to detect
size changes appears to be safer.

I guess I still don't understand what OnResize is useful for. If I
understand it correctly, resizing a control (I can't find any
documentation for what "resize" means, but I assume it means changing
the size via the mouse or keyboard, or when the size changes due to
the parent changing when the control is anchored or docked) results
in:

OnResizeBegin
OnSizeChanged
OnResize
OnResizeEnd

while changing the Size property results in:

OnSizeChanged
OnResize

Since it appears that OnSizeChanged and OnResize always occur in pairs
(assuming that OnSizeChanged calls the base class implementation), why
not just have OnSizeChanged?

Beats me. After several retries due to some framework source code bug I was
able to find a machine that was able to step into Control.OnSizeChanged using
Visual Studio 2008 and all it does is fire OnResize(EventArgs.Empty) as well
as passing on the SizeChanged event to any subscribers.

If you have access to Visual Studio 2008 and want to see for yourself.
Follow this guideline

[Configuring Visual Studio to Debug .NET Framework Source Code]
http://blogs.msdn.com/sburke/archiv...tudio-to-debug-net-framework-source-code.aspx

There might be historical reasons for keeping the Resize event, or perhaps
the SizeChanged event is not needed, but was created because there was a Size
property.

Thanks very much. Since I started using .NET I have been unsure if I
should use OnResize or OnSizeChanged, now I know.

Also thanks for the link. We are moving to VS2008 this week, and I
was not aware that debugging the framework was possible.
 
Which is exactly what I said in the first place and therefore I still wonder
why OnSizeChanged() exists AT ALL. Why not just OnResize()?

And where do these OnResizeBegin() and OnResizeEnd() methods exist? Not in
Framework 2.0, which is what I was referencing.

Apparently they exist only for Form, not for Control.
 
Back
Top