ElektroStudios
ElektroStudios

Reputation: 20464

Prevent Height control resizing at design-time

SCENARIO

When a user drops a TextBox control on the WindowsForms designer, the designer shows only two sizing selectors to resize the width of the control:

enter image description here

...Unless the TextBox.MultiLine property is manually enabled.

But if we add a RichTextBox, it shows 8 sizing selectors:

enter image description here

...even when the RichTextBox.MultiLine property is enabled.

QUESTION

What I would like to do is subclass a RichTextBox class to mimic the sizing behavior that a TextBox has by default at design-time, this means prevent height/corner sizing if the RichTextBox is not multiline.

To be exact, I would like to REMOVE/HIDE the height and corner sizing selectors at design-time, so the subclassed RichTextBox should show only two sizing selectors to resize the width of the control, like in the image above of the TextBox.

I'm aware of the methodology to override SetBoundsCore method to prevent height resizing at design-time, however I would like to go a little bit more far than that solution, because that solution does not remove those sizing selectors ...and just letting the size selectors visible is a ugly and confussing behavior at design-time.

I inspected the official TextBox class source-code to see what happens when the TextBox.MultiLine property value is changed, but I didn't seen anything relevant.

Maybe the DesignerAttribute() class assigned to the TextBox class (System.Windows.Forms.Design.TextBoxBaseDesigner) is involved and maybe it is who decides the sizing behavior at design-time?, in that case what I could do and how to do it?.

Upvotes: 1

Views: 712

Answers (2)

Hans Passant
Hans Passant

Reputation: 941218

This behavior is implemented by the TextBoxBaseDesigner. Also the base class for the RichTextBoxDesigner so you're good with the designer. What is missing here is the AutoSize property, RichTextBox hides it. It needs to be set to True when you change the Multiline property to False. You can't do that from the designer because it is hidden and the default value is False.

That's easily fixable by deriving your own class from RichTextBox:

using System;
using System.ComponentModel;
using System.Windows.Forms;

class RichTextBoxEx : RichTextBox {
    public RichTextBoxEx() {
        base.AutoSize = true;
        base.Multiline = false;
    }
    [DefaultValue(true), Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
    public override bool AutoSize {
        get => base.AutoSize;
        set => base.AutoSize = value;
    }
    [DefaultValue(false)]
    public override bool Multiline {
        get => base.Multiline;
        set {
            base.Multiline = value;
            base.AutoSize = !base.Multiline;
        }
    }
}

Upvotes: 1

Those are called Sizing Handles and are determined by the SelectionRules() method in the designer associated with your control. One thing to keep in mind is that the default for a regular TextBox is MultiLine = False but it is the opposite for a RichTextBox.

The reason you could not find anything relevant in the Reference Source is because the System.Windows.Forms.Design.TextBoxDesigner is internal / Friend. Note also that changing the MultiLine property causes the control to be recreated (RecreateHandle(); in the source).

Imports System.Windows.Forms.Design

<Designer(GetType(RTBElektroDesigner))>
Public Class RTBElektro
    Inherits RichTextBox

    Public Sub New()
    End Sub
End Class

Public Class RTBElektroDesigner
    Inherits System.Windows.Forms.Design.ControlDesigner

    Public Overrides ReadOnly Property SelectionRules() As SelectionRules
        Get
            Dim rtb = TryCast(MyBase.Control, RTBElektro)
            If rtb Is Nothing Then
                Return MyBase.SelectionRules
            Else
                If rtb.Multiline Then
                    Return SelectionRules.AllSizeable Or
                            SelectionRules.Moveable
                Else
                    Return SelectionRules.LeftSizeable Or
                            SelectionRules.RightSizeable Or
                            SelectionRules.Moveable
                End If
            End If
        End Get
    End Property
End Class

Result:

enter image description here

Upvotes: 2

Related Questions