How can I implement an AutoSize property to a Custom Control?
Asked Answered
S

4

7

I want to implement an AutoSize property in a Custom Control (not User Control), in such a way that it behaves like other standard .NET WinForms controls which implement AutoSize (ala CheckBox) in design mode.

I have the property set up, but it's the way the control behaves in design mode that bugs me. it can still be resized, which doesn't make sense because the visual resize isn't reflected in the AutoSize and Size properties i've implemented.

Standard .NET controls do not allow resizing (or even show resize handles) in design mode when AutoSize is true. I want my control to behave in the same fashion.

Edit: I have it working using the SetBoundsCore() override, but it doesn't visually restrict a resize when AutoSize is set to true, it just has the same effect; the functionality is equivalent, but it feels unnatural.

protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified)
{
    if (!this.auto_size)
        this.size = new Size(width, height);
    base.SetBoundsCore(x, y, this.size.Width, this.size.Height, specified);
}

Any ideas on doing this the standard way?

Sitra answered 25/3, 2012 at 0:51 Comment(3)
What UI library are you using? Winforms? WPF? ASP.NET? Something else?Mick
did you try adding sizechanged event, and putting your resize logic there?Potable
Take a look at this #1356732Bricker
C
9

Here's my recipe to have your control AutoSize.

Create a method GetAutoSize() to calculate the required size of the control according to your specific implementation. Maybe it's the size of the text it contains or the total height of the controls for the current width, whatever.

Create a method ResizeForAutoSize() to force the control to resize itself following a change in its state. For example if the control is sized for the text it contains, changing the text should have the control resized. Just call this method when the text changes.

Override GetPreferredSize() to notify whoever wants to know (like a FlowLayoutPanel for instance) what is our preferred size.

Override SetBoundsCore() to enforce our sizing rule the same way an AutoSize label cannot be resized.

See sample here.

/// <summary>
/// Method that forces the control to resize itself when in AutoSize following
/// a change in its state that affect the size.
/// </summary>
private void ResizeForAutoSize()
{
    if( this.AutoSize )
        this.SetBoundsCore( this.Left, this.Top, this.Width, this.Height,
                    BoundsSpecified.Size );
}

/// <summary>
/// Calculate the required size of the control if in AutoSize.
/// </summary>
/// <returns>Size.</returns>
private Size GetAutoSize()
{
    //  Do your specific calculation here...
    Size size = new Size( 100, 20 );

    return size;
}

/// <summary>
/// Retrieves the size of a rectangular area into which
/// a control can be fitted.
/// </summary>
public override Size GetPreferredSize( Size proposedSize )
{
    return GetAutoSize();
}

/// <summary>
/// Performs the work of setting the specified bounds of this control.
/// </summary>
protected override void SetBoundsCore( int x, int y, int width, int height,
        BoundsSpecified specified )
{
    //  Only when the size is affected...
    if( this.AutoSize && ( specified & BoundsSpecified.Size ) != 0 )
    {
        Size size = GetAutoSize();

        width   = size.Width;
        height  = size.Height;
    }

    base.SetBoundsCore( x, y, width, height, specified );
}
Character answered 16/10, 2013 at 17:12 Comment(0)
F
0

In the constructor of your control, call SetAutoSizeMode(AutoSizeMode.GrowAndShrink).

Frisco answered 5/4, 2012 at 0:20 Comment(0)
D
0

Override SizeFromClientSize() method. in this method you must calculate required size for your control and return it.

Disembody answered 11/6, 2013 at 8:18 Comment(0)
S
0

You only need to add this two lines on top of your custom control declaration

[Designer("System.Windows.Forms.Design.LabelDesigner")]
[ToolboxItem("System.Windows.Forms.Design.AutoSizeToolboxItem")]

And naturally implement your Autosize logic

Sideband answered 9/5, 2019 at 10:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.