【问题标题】:Resize form by only specific sizes仅按特定尺寸调整表格大小
【发布时间】:2020-12-14 13:07:28
【问题描述】:

我想允许任何形式的高度,但只允许特定的宽度(300、550、800、...(+250))。我试过这段代码:

Resize += (s, a) => {
    if (Width < 425)
        Width = 300;
    else if (Width < 675)
        Width = 550;
    else if (Width < 925)
        Width = 800;
    else ... 
};

当我尝试调整表单大小时,边框在鼠标位置和预期宽度之间波动。我怎样才能实现这种行为?

【问题讨论】:

    标签: c# winforms resize window-resize


    【解决方案1】:

    我认为问题在于您在 Resize 事件中执行此操作,因此一旦鼠标开始移动,事件就会触发,并且您的代码会调整表单的大小。

    请尝试使用ResizeEnd 事件,该事件仅在用户停止调整大小后触发:

    ResizeEnd += (s, a) =>
    {
        var widths = new[] {300, 550, 800, 1050, 1300, 1550, 1800};
        Width = widths.First(w => Width < w + 125);
    };
    

    【讨论】:

    • 好了。我已经有一段时间没有在 Winforms 工作了
    • 几乎是一个解决方案。如果表单从 300px 大幅调整到 550px,从 1 列数据到 2 列固定大小会更好
    • 我以为您的代码已经这样做了,但您不希望它波动吗?请澄清问题。您的代码有什么问题,您希望看到什么行为?
    • “我以为你的代码已经这样做了,但你不想让它波动吗?”。是的,是的。
    【解决方案2】:

    Form 的 Sizing 或 BeforeResize 事件

    为了控制表单的大小,ResizeEnd 或 SizeChanged 有点晚了,如果你想在这些事件中改变大小,它会导致闪烁。

    要在新尺寸应用之前处理尺寸,您可以处理 WM-SIZING 消息,其中包括建议的尺寸和触发调整大小的表单边缘。

    在以下示例中,我为表单设置了磁贴大小并尝试根据磁贴调整大小:

    private int widthGridSize = 200;
    private int heightGridSize = 1;
    
    private const int WM_SIZING = 0x0214;
    enum EdgeType : int
    {
        WMSZ_LEFT = 1,
        WMSZ_RIGHT = 2,
        WMSZ_TOP = 3,
        WMSZ_TOPLEFT = 4,
        WMSZ_TOPRIGHT = 5,
        WMSZ_BOTTOM = 6,
        WMSZ_BOTTOMLEFT = 7,
        WMSZ_BOTTOMRIGHT = 8
    }
    [StructLayout(LayoutKind.Sequential)]
    public class RECT
    {
        public int L, T, R, B;
        public int W => R - L;
        public int H => B - T;
    }
    protected override void WndProc(ref Message m)
    {
        if (m.Msg == WM_SIZING)
        {
            var flag = (EdgeType)m.WParam;
            var rect = new RECT();
            Marshal.PtrToStructure(m.LParam, rect);
            var w = (int)Math.Round((double)rect.W / widthGridSize) * widthGridSize;
            var h = (int)Math.Round((double)rect.H / heightGridSize) * heightGridSize;
            switch (flag)
            {
                case EdgeType.WMSZ_LEFT:
                    rect.L = rect.R - w;
                    break;
                case EdgeType.WMSZ_RIGHT:
                    rect.R = rect.L + w;
                    break;
                case EdgeType.WMSZ_TOP:
                    rect.T = rect.B - h;
                    break;
                case EdgeType.WMSZ_TOPLEFT:
                    rect.T = rect.B - h;
                    rect.L = rect.R - w;
                    break;
                case EdgeType.WMSZ_TOPRIGHT:
                    rect.T = rect.B - h;
                    rect.R = rect.L + w;
                    break;
                case EdgeType.WMSZ_BOTTOM:
                    rect.B = rect.T + h;
                    break;
                case EdgeType.WMSZ_BOTTOMLEFT:
                    rect.B = rect.T + h;
                    rect.L = rect.R - w;
                    break;
                case EdgeType.WMSZ_BOTTOMRIGHT:
                    rect.B = rect.T + h;
                    break;
                default:
                    break;
            }
            Marshal.StructureToPtr(rect, m.LParam, true);
            m.Result = (IntPtr)1;
        }
        else
            base.WndProc(ref m);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-21
      • 1970-01-01
      • 2012-12-16
      • 1970-01-01
      • 1970-01-01
      • 2020-11-16
      • 1970-01-01
      相关资源
      最近更新 更多