简体   繁体   English

防止高度控制在设计时调整大小

[英]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: 当用户在WindowsForms设计器上删除TextBox控件时,设计器只显示两个大小调整选择器来调整控件的宽度:

在此输入图像描述

...Unless the TextBox.MultiLine property is manually enabled. ...除非手动启用TextBox.MultiLine属性。

But if we add a RichTextBox , it shows 8 sizing selectors: 但是如果我们添加一个RichTextBox ,它会显示8个大小选择器:

在此输入图像描述

...even when the RichTextBox.MultiLine property is enabled. ...即使启用了RichTextBox.MultiLine属性。

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. 我想要做的是将RichTextBox类子类RichTextBox模仿TextBox在设计时默认具有的大小调整行为,这意味着如果RichTextBox不是多行,则防止高度/角大小。

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 . 确切地说,我想在设计时删除/隐藏高度和角度大小选择器,因此子类RichTextBox应该只显示两个大小调整选择器来调整控件的宽度,就像在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. 我知道覆盖SetBoundsCore方法以防止在设计时调整高度的方法 ,但是我想比该解决方案更远一点,因为该解决方案不会删除那些大小选择器......而只是让它可见的大小选择器在设计时是一种丑陋和令人困惑的行为。

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. 我检查了正式的TextBox类源代码,看看TextBox.MultiLine属性值发生变化时会发生什么 ,但我没有看到任何相关内容。

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?. 可能涉及分配给TextBox类( System.Windows.Forms.Design.TextBoxBaseDesigner )的DesignerAttribute()类,也许是谁在设计时决定了大小调整行为?在这种情况下我可以做什么以及如何做它?。

Those are called Sizing Handles and are determined by the SelectionRules() method in the designer associated with your control. 这些称为大小句柄 ,由与控件关联的设计器中的SelectionRules()方法确定。 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 . 要记住的一件事是常规TextBox的默认值是MultiLine = False但它与RichTextBox相反。

The reason you could not find anything relevant in the Reference Source is because the System.Windows.Forms.Design.TextBoxDesigner is internal / Friend . 您在参考源中找不到任何相关内容的原因是因为System.Windows.Forms.Design.TextBoxDesignerinternal / Friend Note also that changing the MultiLine property causes the control to be recreated ( RecreateHandle(); in the source). 另请注意,更改MultiLine属性会导致重新RecreateHandle();控件(源中的RecreateHandle(); )。

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: 结果:

在此输入图像描述

This behavior is implemented by the TextBoxBaseDesigner. 此行为由TextBoxBaseDesigner实现。 Also the base class for the RichTextBoxDesigner so you're good with the designer. 也是RichTextBoxDesigner的基类,所以你对设计师很好。 What is missing here is the AutoSize property, RichTextBox hides it. 这里缺少的是AutoSize属性,RichTextBox隐藏它。 It needs to be set to True when you change the Multiline property to False. 将Multiline属性更改为False时,需要将其设置为True。 You can't do that from the designer because it is hidden and the default value is False. 您无法从设计器执行此操作,因为它是隐藏的,默认值为False。

That's easily fixable by deriving your own class from RichTextBox: 通过从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;
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM