【问题标题】:Vertically (only) resizable windows form in C#C# 中垂直(仅)可调整大小的窗口窗体
【发布时间】:2011-01-09 14:21:46
【问题描述】:

我有一种情况,允许用户调整我的 windows 窗体的大小对我来说是有益的,但只能垂直调整。经过一番搜索,似乎关于这个特定主题的内容并不多。有可能吗?

【问题讨论】:

  • @Will:这取决于表单显示的内容。在某些情况下,这是个好主意。
  • @slaks 从未见过。看到很多应用程序认为他们知道表单应该有多大。 Visual Studio 仍然有一些。这些表格有一个共同点——制作它们的人对“正确”的尺寸是错误的。在所有情况下,让用户决定表单的大小,否则会有被诅咒的风险。 (完全披露,我冒着被诅咒的风险。我很惭愧。)
  • @Will:Virtual PC 2007怎么样?
  • @dada686 在 Vista 上,Freecell 可以调整大小和缩放,这很棒。我来到这里是因为我有一个 3 行窗口:两个文本字段和一个按钮。所以垂直调整它的大小没有意义,对吧......?好吧,我不再那么确定了。对于垂直调整大小,我可以使文本字段更高,字体更大!这是一个不寻常的功能,但它不会受到伤害。

标签: c# winforms resize


【解决方案1】:

让FormBorderStyle为Resizable,设置MaximumSize和MinimumSize = new Size(this.Width, 0)

更正

this.MinimumSize = new Size(this.Width, 0);
this.MaximumSize = new Size(this.Width, Int32.MaxValue);

【讨论】:

  • MinimumSize 和 MaximumSize 分量仅在两个分量都为零时才被解释为“无限制”。
  • @SLaks,你说得对!高度需要设置为最小和最大尺寸的不同值。
【解决方案2】:

您需要将表单的MinimumSizeMaximumSize 属性设置为高度不同但宽度相等的两种尺寸。

如果您根本不希望出现水平调整大小光标,则需要处理 WM_NCHITTEST 消息,如下所示:

protected override void WndProc(ref Message m) {
    base.WndProc(ref m);
    switch (m.Msg) {
        case 0x84: //WM_NCHITTEST
            var result = (HitTest)m.Result.ToInt32();
            if (result == HitTest.Left || result == HitTest.Right)
                m.Result = new IntPtr((int)HitTest.Caption);
            if (result == HitTest.TopLeft || result == HitTest.TopRight)
                m.Result = new IntPtr((int)HitTest.Top);
            if (result == HitTest.BottomLeft || result == HitTest.BottomRight)
                m.Result = new IntPtr((int)HitTest.Bottom);

            break;
    }
}
enum HitTest {
    Caption = 2,
    Transparent = -1,
    Nowhere = 0,
    Client = 1,
    Left = 10,
    Right = 11,
    Top = 12,
    TopLeft = 13,
    TopRight = 14,
    Bottom = 15,
    BottomLeft = 16,
    BottomRight = 17,
    Border = 18
}

【讨论】:

  • 不敢相信我没有想到这个......非常好!并感谢隐藏调整大小光标的 WndProc 细节!
  • 只是一个评论......你不应该让 HitTest.Left 和 .Right 返回 None 而不是 Caption?使用 Caption 使窗口可以在这些位置拖动,不是吗?
  • @MarqueIV:是的;我认为这是一个功能。
  • 我同意这是一个不错的功能——能够从标题以外的地方拖动窗口,但如果你要走那条路,我会在任何地方做NCHitTest 通常会返回 None,因此您也可以从客户区的其他部分拖动它。如果不允许这样做,则不会向用户提供任何区别或反馈,即边缘具有不同的行为,而如果它总是无论如何移动,它就会移动。当然玩我自己的对手,我也可以说允许从标题以外的任何地方移动也是一个不一致的界面,所以也是如此。
【解决方案3】:

为了避免@orsogufo 解决方案的“橡皮筋”效应:

public Form1()
{
    InitializeComponent();
    this.MinimumSize = new Size(500, 0);
    this.MaximumSize = new Size(500, Screen.AllScreens.Max(s => s.Bounds.Height));
}

如果您调整屏幕边界大小,它不会正确调整其最大高度以适应更大的屏幕,但对于静态屏幕尺寸,它的效果很好。

【讨论】:

    【解决方案4】:

    是的,这是可能的。只需设置您的 form.MinimumSize.Width = form.MaximumSize.Width = 100(或您想要的任何宽度)。

    【讨论】:

    • 您不能直接将宽度指定为 form.MinimunSize 或 form.MaximumSize 返回值类型,而不是引用。
    • 这不是一个工作代码示例,只是对应该设置什么的想法。
    • 我无法理解人们在尝试理解简单语句时如何忘记使用逻辑。 +1
    【解决方案5】:

    只是一个想法......

    public partial class Form1 : Form {
        int _width;
    
        public Form1() {
            _width = this.Width;
            InitializeComponent();
        }
    
        protected override void OnResize(EventArgs e) {
            this.Width = _width;
            base.OnResize(e);
        }
    }
    

    编辑:请注意,最小/最大尺寸解决方案比这个 hack 效果更好 :)

    【讨论】:

    • 打败我。 +1 对于其他解决方案,我不确定是否可以在不设置最大/最小高度的情况下实际具有最大/最小宽度。此解决方案将允许您调整表单的大小,但它会将橡皮筋带回原来的宽度。
    • @George:你可以设置一个小的最小值和一个非常大的最大值。
    【解决方案6】:

    仅设置表单宽度的最大和最小尺寸。

    【讨论】:

    • 确保在 Load 事件中这样做,而不是在构造函数中这样做。或者自动缩放会剪切表单内容。
    • 如果您将MinimumSize 和MaximumSize 属性的高度分量保留为0,但设置了宽度,则会将窗口限制为最小高度。 MinimumSize 和 MaximumSize 约束仅在两个分量都为零时才被忽略 - 如果一个设置而另一个保持为零,它将按字面意思强制这两个分量。
    • 在设计时在属性窗格中执行此操作。无需使用任何代码使表单仅垂直滚动。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-16
    相关资源
    最近更新 更多