1

I have a custom UserControl which draws text and graphics using GDI+. Normally I dock it using DockStyle.Bottom within another control.

The size of this control is determined by a custom layout using Graphics.MeasureString(). Therefore, it needs to recalculate the height everytime the width changes, which is changed when the parent width changes.

Currently I am setting this control's height in its OnSizeChanged event. However I am noticing some bugs with this. Sometimes when I resize the parent, the control is not touching the bottom of the parent, even though it is set to DockStyle.Bottom. I used Spy++ to analyze the control bounds and there is simply some empty space between the control and the edge of the parent by about 20 pixels.

I want to implement a proper AutoSize in this UserControl assuming a Top or Bottom DockStyle.

Trevor Elliott
  • 11,292
  • 11
  • 63
  • 102
  • tried setting AutoSize to true for both the FlowLayoutPanel and the UserControl itself? – Dmitry Savy Feb 27 '12 at 22:14
  • Is there something wrong with using FlowLayoutPanel for this. Or how about setting Anchor? If you use anchors and dock on all controls in your user control and set them to dock the edges of the control, the controls will resize with the UserControl and you can now set anchors/dock to the UserControl also. When you combine the Anchor and Dock property of the UserControl to set options so that the edges of your control displays to some other parts of your UI. When the UI gets resized, your control will also get resized properly. – Dmitry Savy Feb 27 '12 at 22:29
  • I don't have controls in my UserControl. I have custom drawn content. Anchor does not apply in this situation since the size is not determined by the parent, only the Width is determined by the parent. The height needs to be determined by the child based on the width. I know there is a standard for doing this (it's how all AutoSize controls work in Winforms) and I assume it's by overriding GetPreferredSize(), but I have yet to find an actual sample implementation. – Trevor Elliott Feb 27 '12 at 22:39
  • Does this thread help? http://stackoverflow.com/questions/8493843/how-to-override-the-preferred-size-of-a-winforms-textbox – Dmitry Savy Feb 27 '12 at 22:49

1 Answers1

1

The DefaultLayout engine for WindowsForms has quite a bit logic in there for laying out docked controls. I would recommend a decompiler (dotPeek, Reflector, etc.) and decompile the DefaultLayout class.

There is a lot interaction between the control itself, its children, whether it overrides GetPreferredSize etc. etc.

Perhaps when you understand the context under which your GetPreferredSize is called, you'll get a better idea of how to implement it.

In terms of sample implementations, again, what better than the Windows controls themselves? Decompile a few. Here'as an example from ToolStripItem

 public virtual Size GetPreferredSize(Size constrainingSize)
    {
      constrainingSize = LayoutUtils.ConvertZeroToUnbounded(constrainingSize);
      return this.InternalLayout.GetPreferredSize(constrainingSize - this.Padding.Size) + this.Padding.Size;
    }

Good luck!

Steven P
  • 1,956
  • 1
  • 16
  • 17