【问题标题】:Prevent Height control resizing at design-time防止高度控制在设计时调整大小
【发布时间】:2017-04-13 11:46:13
【问题描述】:

场景

当用户在 WindowsForms 设计器上放置 TextBox 控件时,设计器仅显示两个大小选择器来调整控件的宽度:

...除非手动启用TextBox.MultiLine 属性。

但如果我们添加一个RichTextBox,它会显示 8 个尺寸选择器:

...即使启用了RichTextBox.MultiLine 属性。

问题

我想做的是子类RichTextBox 类来模仿TextBox 在设计时默认具有的大小调整行为,这意味着如果RichTextBox 不是多行,则防止高度/角大小调整。

确切地说,我想在设计时移除/隐藏高度和角尺寸选择器,因此子类RichTextBox 应该只显示两个尺寸选择器来调整控件的宽度,如上图所示TextBox.

我知道 the methodology to override SetBoundsCore method 可以防止在设计时调整高度大小,但是我想比那个解决方案走得更远一些,因为那个解决方案不会删除这些大小选择器 ...并且仅让尺寸选择器可见是设计时丑陋且令人困惑的行为。

我查看了官方的TextBox类源代码看到what happens when the TextBox.MultiLine property value is changed,但我没有看到任何相关的东西。

也许涉及分配给TextBox 类(System.Windows.Forms.Design.TextBoxBaseDesigner)的DesignerAttribute() 类,也许是在设计时决定大小行为的人?在这种情况下,我可以做什么以及如何做?.

【问题讨论】:

    标签: c# .net vb.net visual-studio windows-forms-designer


    【解决方案1】:

    这些被称为 Sizing Handles,由与您的控件关联的设计器中的SelectionRules() 方法确定。要记住的一件事是,常规 TextBox 的默认值是 MultiLine = False,但 RichTextBox 的默认值正好相反。

    您在参考源中找不到任何相关内容的原因是System.Windows.Forms.Design.TextBoxDesignerinternal / Friend。另请注意,更改 MultiLine 属性会导致重新创建控件(源代码中的 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
    

    结果:

    【讨论】:

    • 谢谢,这两个答案都很聪明,都值得点和知识钦佩,但覆盖 RichTextBox.MultiLine 属性是最简单的方法。 (只是解释我接受@Hans Passant 答案的原因)
    【解决方案2】:

    此行为由 TextBoxBaseDesigner 实现。也是 RichTextBoxDesigner 的基类,因此您可以很好地使用设计器。这里缺少的是 AutoSize 属性,RichTextBox 隐藏了它。将 Multiline 属性更改为 False 时,需要将其设置为 True。您不能从设计器中执行此操作,因为它是隐藏的并且默认值为 False。

    这很容易通过从 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;
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多