在Windows窗体应用程序C#中围绕所有对象绘制矩形

问题描述 投票:0回答:1

我使用对象周围的矩形(如按钮、标签等)来通过最大化窗口自动调整其大小和位置。

这是我的函数和代码。

private async Task ResizeControlAsync(Control c, Rectangle r) // resize buttons, panels, etc.
        {
            float xRatio = (float)(this.Width) / (float)(formOriginalSize.Width);
            float yRatio = (float)(this.Height) / (float)(formOriginalSize.Height);
            int newX = (int)(r.X * xRatio);
            int newY = (int)(r.Y * yRatio);

            int newWidth = (int)(r.Width * xRatio);
            int newHeight = (int)(r.Height * yRatio);
            
                await Task.Run(() =>
                {
                    c.Invoke((MethodInvoker)(() =>
                    {

                            if (!isminimized)
                            {
                                c.Location = new Point(newX, newY);
                                c.Size = new Size(newWidth, newHeight);
                               
                            }
                    }));
                });
        }
private async void Form1_Resize(object sender, EventArgs e)
        {
            isminimized = WindowState == FormWindowState.Minimized;
            

            //resize_page(Pages);
            await ResizeControlAsync(MainPanel_BehindPagesObject, rec_MainPanel_BehindPagesObject);
            await ResizeControlAsync(MainPanel_Background, rec_MainPanel_Background);
            await ResizeControlAsync(SeparatorLine, rec_SeparatorLine);

            // Menu Panel
            await ResizeControlAsync(MenuPanel, rec_MenuPanel);
            //await ResizeControlAsync(Pad_Small, rec_Pad_Small);
            

            await ResizeControlAsync(MainButton, rec_MainButton);
            await ResizeControlAsync(DisplayButton, rec_DisplayButton);
            ...


        }

rec_Object_Name,是我手动定义的矩形:

        private Rectangle rec_MainPanel_BehindPagesObject;
        private Rectangle rec_MainPanel_Background;
        private Rectangle rec_SeparatorLine;

        // first panel (connection) 
        private Rectangle rec_ConnectionPanel;
        private Rectangle rec_ConnectButton;     // rec is abbreviation of rectangle.
        private Rectangle rec_RefreshPorts;      // rec is abbreviation of rectangle.

我想让这个过程变得更容易。事实上,围绕每个对象定义记录是一种负担! 此外,我正在为 Form1_Resize 中的每个项目调用 ResizeControlAsync!!!

这需要很多时间而且根本不干净!!

我尝试了这样的代码来查找我的应用程序中的所有对象并围绕它们创建一个记录。但是,使用此代码没有找到任何对象。因此不会创建新的矩形!

简而言之: `//获取表单上的所有控件

var controls = this.Controls;

` 控件返回空!

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Reflection;
using System.Windows.Forms;

class Program
{
    static void Main()
    {
        // Create a new instance of your form
        Form form = new Form();

        // Define a list to store the rectangles
        List<Rectangle> rectangles = GetRectanglesAroundControls(form);

        // Use the rectangles as needed

        Console.ReadKey();
    }

    static List<Rectangle> GetRectanglesAroundControls(Control parentControl)
    {
        List<Rectangle> rectangles = new List<Rectangle>();

        AddControlRectangles(parentControl, rectangles);

        return rectangles;
    }

    static void AddControlRectangles(Control control, List<Rectangle> rectangles)
    {
        Rectangle rectangle = GetRectangleAroundControl(control);
        rectangles.Add(rectangle);

        // Recursively process child controls
        foreach (Control childControl in control.Controls)
        {
            AddControlRectangles(childControl, rectangles);
        }
    }

    static Rectangle GetRectangleAroundControl(Control control)
    {
        Point location = control.Location;
        Size size = control.Size;
        return new Rectangle(location, size);
    }
}
c# winforms
1个回答
2
投票

在每个控件周围创建一个

Rectangle
并没有真正意义,因为每个
Control
已经有了自己的矩形(
Location
Size
ClientRectangle
如果您只对表单内容感兴趣。)

您绝对应该熟悉每个控件的

Anchor
属性,而不是手动调整大小和调整。设置正确后,每个控件都会自动调整大小,而不需要进行任何类型的手动调整大小。
SplitPanels
提供了一种让表单布局有效适应尺寸变化的方法。

我们有一个巨大的表单应用程序,除了一些特殊情况(例如“居中”)之外,绝对不需要手动调整任何控件来实现流畅的布局。


根据您的评论,您似乎想要实现“我的表单增长了 50%,因此每个控件都应该增长 50%”之类的目标。对于应用程序来说,这是一种非常不自然且不直观的行为。

通常,您有一个控件(或列表)形成中心对象,而其他控件则排列在它周围作为支持元素。

通过锚定,现在可以很容易地说:主元素锚定到所有 4 个边缘,因此可以完美地随表单增长,而所有其他元素锚定到最多 2 个边缘(左上、右下等),以保持其相对位置形式,但保持其大小。

对于您的用例,实现您想要的效果的最佳镜头是

tableLayoutPanel

  • 定义一定数量的列/行。
  • 设置每个表/行分别消耗
    1/count
    % of
    height
    with
  • 将这个新盒子视为您的新
    layoutPixels
    任何控件都可以消耗:

现在,您可以添加一个

control
,提供
row
column
跨度,将其停靠模式设置为
fill
- 并让控件在所有维度上随表单大小相对增大或缩小:

理论上您可以构建一个由 100 列和 100 行组成的网格,允许您以 1% 的步长“设置”控件的高度、宽度和位置。

© www.soinside.com 2019 - 2024. All rights reserved.