panel中动态添加的子窗体自适应分辨率

winform中我的主窗体中利用panel来动态添加子窗体(点击按钮就可以切换成其他的子窗体),现在我用使窗体和控件随着分辨率去自适应大小和位置咋解决

我想要达到的结果
 private void button_Realt_Click(object sender, EventArgs e)
        {
            this.pnlMain.Controls.Clear();
            RealtimeInfoForm realtimeInfoForm = new RealtimeInfoForm();
            realtimeInfoForm.TopLevel = false;
            realtimeInfoForm.Show();
            this.pnlMain.Controls.Add(realtimeInfoForm);

        }

        private void button_Contro_Click(object sender, EventArgs e)
        {
            this.pnlMain.Controls.Clear();
            ControllerSettingsForm controllerSettingsForm = new ControllerSettingsForm();
            controllerSettingsForm.TopLevel = false;
            controllerSettingsForm.Show();
            this.pnlMain.Controls.Add(controllerSettingsForm);
        }
这是我利用panel添加的子窗体代码
        float xvalues;
        float yvalues;
        /// <summary>
        /// 改变控件大小
        /// </summary>
        private void SetControls(float newX, float newY, Control cons)
        {
            foreach (Control con in cons.Controls)
            {
                
                string[] mytag = con.Tag.ToString().Split(new char[] { ':' });
                float a = Convert.ToSingle(mytag[0]) * newX;
                con.Width = (int)a;
                a = Convert.ToSingle(mytag[1]) * newY;
                con.Height = (int)a;

                a = Convert.ToSingle(mytag[2]) * newX;
                con.Left = (int)a;
                a = Convert.ToSingle(mytag[3]) * newY;
                con.Top = (int)a;

                Single currentSize = Convert.ToSingle(mytag[4]) * newY;
                con.Font = new Font(con.Font.Name, currentSize, con.Font.Style, con.Font.Unit);

                if (con.Controls.Count > 0)
                {
                    SetControls(newX, newY, con);
                }
            }
        }
        /// <summary>
        /// 遍历窗体中控件的函数
        /// </summary>
        /// <param name="cons"></param>
        private void SetTag(Control cons)
        {
            //遍历窗体中的控件,记录控件初始大小
            foreach (Control con in cons.Controls)
            {
                con.Tag = con.Width + ":" + con.Height + ":" + con.Left + ":" + con.Top + ":" + con.Font.Size;
                if (con.Controls.Count > 0)
                {
                    SetTag(con);
                }
            }
        }
        private void Form1_Resize(object sender, EventArgs e)
        {
            //throw new NotImplementedException();
            float newX = this.Width / xvalues;//获取比列
            float newY = this.Height / yvalues;
            SetControls(newX, newY, this);
        }
       
        private void DetailForm_Load(object sender, EventArgs e)
        {
            #region 自适应

            this.Resize += new EventHandler(Form1_Resize);//添加窗体拉伸重绘事件
            xvalues = this.Width;//记录窗体初始大小
            yvalues = this.Height;
            SetTag(this);
            #endregion

            if (ChooseForm == 1)
            {
                this.pnlMain.Controls.Clear();
                FirmwareForm firmwareForm = new FirmwareForm();
                firmwareForm.TopLevel = false;
                firmwareForm.Show();
                this.pnlMain.Controls.Add(firmwareForm);
            }
            else if (ChooseForm == 2)
            {
                this.pnlMain.Controls.Clear();
                Diagnostic diagnosticForm = new Diagnostic();
                diagnosticForm.TopLevel = false;
                diagnosticForm.Show();
                this.pnlMain.Controls.Add(diagnosticForm);
            }
            else if (ChooseForm == 3)
            {
                this.pnlMain.Controls.Clear();
                RealtimeInfoForm realtimeInfoForm = new RealtimeInfoForm();
                realtimeInfoForm.TopLevel = false;
                realtimeInfoForm.Show();
                this.pnlMain.Controls.Add(realtimeInfoForm);
            }
            else if (ChooseForm == 4)
            {
                this.pnlMain.Controls.Clear();
                ControllerSettingsForm controllerSettingsForm = new ControllerSettingsForm();
                controllerSettingsForm.TopLevel = false;
                controllerSettingsForm.Show();
                this.pnlMain.Controls.Add(controllerSettingsForm);
            }
        }
这是我窗体自适应的代码,但是panel动态添加窗体那边不能自适应分辨率

用tablelayoutpanel控件,自动缩放

在WinForms中实现窗体和控件的自适应可以分为以下几个步骤:

使用Anchors和Dock属性:Anchors属性可以帮助控件随着窗体大小改变而调整位置,Dock属性可以将控件固定在窗体的边界或填充整个窗体。

使用TableLayoutPanel或FlowLayoutPanel:这两个容器控件可以帮助您更轻松地布局子控件,并在窗体大小改变时自动调整。

使用AutoSize和AutoSizeMode属性:这些属性可用于设置控件的自动大小和自动调整行为。

手动调整控件大小和位置:在窗体的Resize事件中,手动计算并调整控件的大小和位置,以实现自适应效果。

根据您提供的代码,您正在使用手动调整控件大小和位置的方式。在这种情况下,确保以下几点:

设置Panel的Anchor属性:在您的pnlMain Panel上设置Anchor属性,以便Panel能够随着窗体大小改变而调整大小。您可以选择设置为Left、Top、Right、Bottom来让Panel占据整个窗体。

适当设置子窗体的Anchor或Dock属性:确保您的子窗体在Panel中有正确的布局,可以使用Anchors属性或Dock属性来调整子窗体的位置和大小。

确保Panel的AutoSize属性为false:Panel的AutoSize属性默认为true,这会导致Panel的大小随着其内容变化。设置为false,以便Panel的大小由Anchor或Dock属性决定。

在Form1_Resize事件中调用子控件的自适应:在Form1_Resize事件中,调用SetControls方法,确保所有子控件都根据新的窗体大小进行适当调整。

确保所有控件有正确的初始大小和位置:在Form1_Load事件中调用SetTag方法,为所有控件设置初始大小和位置。

【以下回答由 GPT 生成】

问题分析: 要使动态添加到Panel中的子窗体能够自适应分辨率,需要考虑以下几个方面: 1. 子窗体和控件的大小和位置: - 子窗体应该随着窗口大小的变化而自动调整大小和位置。 - 控件应该根据窗口大小的变化以比例调整大小和位置。 2. 字体大小: - 字体大小应该根据窗口大小的变化以比例调整。 3. 响应窗口大小变化的事件: - 当窗口大小变化时,需要重新计算子窗体和控件的大小和位置,并更新字体大小。

解决方案: 1. 在主窗体的构造函数中添加窗口大小变化的事件处理程序: c# this.Resize += new EventHandler(MainForm_Resize); 2. 实现窗口大小变化的事件处理程序,重新计算子窗体和控件的大小和位置,并更新字体大小: c# private void MainForm_Resize(object sender, EventArgs e) { float newX = (float)this.Width / xvalues; float newY = (float)this.Height / yvalues; SetControls(newX, newY, this); } 3. 修改SetControls方法,添加在控件大小和位置调整后,将xvalues和yvalues更新为当前窗口大小的代码: ```c# private void SetControls(float newX, float newY, Control cons) { foreach (Control con in cons.Controls) { string[] mytag = con.Tag.ToString().Split(new char[] { ':' }); float a = Convert.ToSingle(mytag[0]) * newX; con.Width = (int)a; a = Convert.ToSingle(mytag[1]) * newY; con.Height = (int)a;

       a = Convert.ToSingle(mytag[2]) * newX;
       con.Left = (int)a;
       a = Convert.ToSingle(mytag[3]) * newY;
       con.Top = (int)a;

       Single currentSize = Convert.ToSingle(mytag[4]) * newY;
       con.Font = new Font(con.Font.Name, currentSize, con.Font.Style, con.Font.Unit);
   }
   xvalues = cons.Width;
   yvalues = cons.Height;

} ```

完整代码:

// 切换到实时信息子窗体
private void button_Realt_Click(object sender, EventArgs e)
{
    this.pnlMain.Controls.Clear();
    RealtimeInfoForm realtimeInfoForm = new RealtimeInfoForm();
    realtimeInfoForm.Tag = "1:1;1:1;1:1;1:1;1:1"; // 设置控件大小和位置的比例
    realtimeInfoForm.TopLevel = false;
    realtimeInfoForm.Show();
    this.pnlMain.Controls.Add(realtimeInfoForm);
    SetControls((float)this.pnlMain.Width / xvalues, (float)this.pnlMain.Height / yvalues, this.pnlMain);
}

// 切换到控制器设置子窗体
private void button_Contro_Click(object sender, EventArgs e)
{
    this.pnlMain.Controls.Clear();
    ControllerSettingsForm controllerSettingsForm = new ControllerSettingsForm();
    controllerSettingsForm.Tag = "1:1;1:1;1:1;1:1;1:1"; // 设置控件大小和位置的比例
    controllerSettingsForm.TopLevel = false;
    controllerSettingsForm.Show();
    this.pnlMain.Controls.Add(controllerSettingsForm);
    SetControls((float)this.pnlMain.Width / xvalues, (float)this.pnlMain.Height / yvalues, this.pnlMain);
}

// 改变控件大小
private void SetControls(float newX, float newY, Control cons)
{
    foreach (Control con in cons.Controls)
    {
        string[] mytag = con.Tag.ToString().Split(new char[] { ':' });
        float a = Convert.ToSingle(mytag[0]) * newX;
        con.Width = (int)a;
        a = Convert.ToSingle(mytag[1]) * newY;
        con.Height = (int)a;

        a = Convert.ToSingle(mytag[2]) * newX;
        con.Left = (int)a;
        a = Convert.ToSingle(mytag[3]) * newY;
        con.Top = (int)a;

        Single currentSize = Convert.ToSingle(mytag[4]) * newY;
        con.Font = new Font(con.Font.Name, currentSize, con.Font.Style, con.Font.Unit);
    }
    xvalues = cons.Width;
    yvalues = cons.Height;
}

// 窗口大小变化事件处理程序
private void MainForm_Resize(object sender, EventArgs e)
{
    float newX = (float)this.pnlMain.Width / xvalues;
    float newY = (float)this.pnlMain.Height / yvalues;
    SetControls(newX, newY, this.pnlMain);
}

// 主窗体构造函数
public MainForm()
{
    InitializeComponent();
    xvalues = this.pnlMain.Width;
    yvalues = this.pnlMain.Height;
    this.Resize += new EventHandler(MainForm_Resize);
}

解决方案如上所示。该方案会在切换子窗体时根据窗口大小自动调整控件的大小和位置,以及字体的大小。请注意,在切换子窗体后,需要调用一次SetControls方法,以使动态添加的子窗体开始自适应大小和位置。



【相关推荐】



如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

提供参考实例,winform窗体程序适应不同的分辨率,链接:https://www.cnblogs.com/hanzq/p/16731599.html
实例思路:
1、窗体加载时获取窗体的长x1和宽y1;
2、使用窗体的Resize()事件,当窗体尺寸发生变化时,获得窗体变化后的长x2和宽y2,将x2/x1得到kx,将y2/y1得到ky
3、遍历窗体中的所有控件,将控件的位置,大小,字体大小按照kx和ky比例进行调整;

🟢参考GPT:

在进行panel动态添加窗体的过程中,我们需要注意让窗体能够自适应不同的分辨率。为了实现这一点,可以按照以下步骤进行操作:


1、创建一个panel,作为容器来放置动态添加的窗体。设置panel的Dock属性为Fill,这样可以让panel充满整个父容器。

2、在需要动态添加窗体的代码段中,创建一个新的窗体对象,并将其添加到panel中。可以使用panel.Controls.Add()方法来实现。

3、在添加窗体前,先设置新窗体的AutoSize属性为true,这样可以让窗体根据其内容自动调整大小。

4、在窗体被添加到panel后,设置窗体的Dock属性为Fill,这样可以让窗体充满panel的空间。

不知道有没有考虑使用TabControl,会更好用。
Panel切换的话,可以考虑在直接使用多个Panel重叠,再在使用的时候调整层次或者设置可见不可见来控制显示,这样可以减少重建的开销,布局也更好处理。多个panel的编辑可以使用文档大纲,很方便

img

动态要改好多代码了要

要实现窗体自适应分辨率,包括动态添加的子窗体,可以按照以下步骤进行操作:

  1. 在主窗体的Form1_Resize事件中,计算新的比例newXnewY,并调用SetControls方法来设置控件的大小和位置。
private void Form1_Resize(object sender, EventArgs e)
{
    float newX = this.Width / xvalues;
    float newY = this.Height / yvalues;
    SetControls(newX, newY, this.pnlMain);
}
  1. 修改SetControls方法,使其能够递归设置子控件的大小和位置。
private void SetControls(float newX, float newY, Control cons)
{
    foreach (Control con in cons.Controls)
    {
        string[] mytag = con.Tag.ToString().Split(new char[] { ':' });
        float a = Convert.ToSingle(mytag[0]) * newX;
        con.Width = (int)a;
        a = Convert.ToSingle(mytag[1]) * newY;
        con.Height = (int)a;

        a = Convert.ToSingle(mytag[2]) * newX;
        con.Left = (int)a;
        a = Convert.ToSingle(mytag[3]) * newY;
        con.Top = (int)a;

        Single currentSize = Convert.ToSingle(mytag[4]) * newY;
        con.Font = new Font(con.Font.Name, currentSize, con.Font.Style, con.Font.Unit);

        if (con.Controls.Count > 0)
        {
            SetControls(newX, newY, con);
        }
    }
}
  1. 在每个子窗体的Load事件中,调用SetTag方法来记录控件的初始大小。
private void RealtimeInfoForm_Load(object sender, EventArgs e)
{
    SetTag(this);
}
  1. 在每个子窗体的SizeChanged事件中,调用SetControls方法来重新设置控件的大小和位置。
private void RealtimeInfoForm_SizeChanged(object sender, EventArgs e)
{
    float newX = this.Width / xvalues;
    float newY = this.Height / yvalues;
    SetControls(newX, newY, this);
}

通过以上步骤,主窗体和子窗体都能够根据分辨率自适应调整大小和位置。

在panel中动态添加子窗体,能够实现一个窗口内部分区域的功能,而自适应分辨率的实现则需要考虑如下几个方面:

  1. 窗口大小变化
    当窗口大小变化时,子窗体的大小也需要跟着变化。可以通过panel的SizeChanged事件来实现,当panel的大小发生变化时,同时改变子窗体的大小,从而达到自适应分辨率的效果。代码如下:
private void panel1_SizeChanged(object sender, EventArgs e)
{
    foreach (Control c in panel1.Controls)
    {
        c.Size = panel1.Size;
    }
}

上述代码中,panel1_SizeChanged事件中循环遍历panel1中的所有子控件,将它们的大小设置为panel1的大小。

  1. 控件位置变化
    当窗口大小变化时,子窗体的位置也需要跟着变化,否则子窗体可能会被覆盖或者错位。为了解决这个问题,需要在控件的LocationChanged事件中处理控件的位置,从而保证子窗体的位置始终与panel的位置保持一致。代码如下:
private void Form1_Load(object sender, EventArgs e)
{
    MyForm myForm = new MyForm();
    myForm.TopLevel = false;
    myForm.Parent = panel1;
    myForm.Location = new Point(0, 0);
    myForm.Show();
    myForm.LocationChanged += new EventHandler(MyForm_LocationChanged);
}

private void MyForm_LocationChanged(object sender, EventArgs e)
{
    Control c = sender as Control;
    if (c != null)
    {
        Point p = c.Location;
        p.Offset(panel1.Location);
        c.Parent.Invalidate(new Rectangle(p, c.Size), true);
    }
}

上述代码中,MyForm_LocationChanged事件中将控件的位置偏移了panel1的位置,然后再使用Invalidate方法来更新控件的位置。

  1. 窗口缩放
    在Windows上的很多程序中,用户可以通过鼠标滚轮或者快捷键来缩放窗口,这样可以使得程序更加灵活。为了实现这个功能,需要定义一个缩放比例,并在窗口缩放时动态改变子窗体的大小。代码如下:
private const float ScaleStep = 0.1f;
private const float ScaleMax = 2.0f;
private const float ScaleMin = 0.1f;
private float _scale = 1.0f;

private void panel1_MouseWheel(object sender, MouseEventArgs e)
{
    float delta = e.Delta / 120.0f;
    if (delta > 0 && _scale < ScaleMax)
    {
        _scale += ScaleStep;
    }
    else if (delta < 0 && _scale > ScaleMin)
    {
        _scale -= ScaleStep;
    }
    foreach (Control c in panel1.Controls)
    {
        c.Size = new Size((int)(panel1.ClientSize.Width * _scale), (int)(panel1.ClientSize.Height * _scale));
    }
}

上述代码中,panel1_MouseWheel事件中计算出鼠标滚轮的变化值,然后根据缩放比例动态改变子窗体的大小,从而达到自适应分辨率的效果。

以上就是在panel中动态添加子窗体自适应分辨率内容的详细说明,实现自适应分辨率需要注意控件的大小和位置,以及缩放比例等因素。只要按照以上步骤来实现,就可以轻松实现自适应分辨率的功能。

为了实现子窗体自适应分辨率,需要在子窗体的代码中进行以下操作:

  1. 在子窗体的Load事件中添加代码,使窗体随着分辨率自适应大小:
this.AutoSize = true;
this.AutoSizeMode = AutoSizeMode.GrowAndShrink;
  1. 在子窗体的Resize事件中添加代码,使控件随着窗体大小改变而自适应大小和位置:
foreach (Control control in this.Controls)
{
    control.Left = (this.Width - control.Width) / 2;
    control.Top = (this.Height - control.Height) / 2;
    control.Anchor = AnchorStyles.None;
    control.Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top | AnchorStyles.Bottom;
}

这段代码会遍历所有控件,设定控件的位置和锚定方式,以保证控件随着窗体变化而自适应。

  1. 在父窗体中的代码中,添加切换子窗体的逻辑,同时让子窗体随父窗体的大小改变而自适应:
private void switchChildForm(Form form)
{
    panel.Controls.Clear();
    form.TopLevel = false;
    form.AutoSize = true;
    form.AutoSizeMode = AutoSizeMode.GrowAndShrink;
    panel.Controls.Add(form);
    form.Show();
}

private void MainForm_Resize(object sender, EventArgs e)
{
    foreach (Control control in panel.Controls)
    {
        control.Left = (panel.Width - control.Width) / 2;
        control.Top = (panel.Height - control.Height) / 2;
        control.Anchor = AnchorStyles.None;
        control.Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top | AnchorStyles.Bottom;
    }
}

private void button1_Click(object sender, EventArgs e)
{
    Form1 form1 = new Form1();
    switchChildForm(form1);
}

在switchChildForm函数中,先将子窗体的AutoSize和AutoSizeMode设为true,再使用panel.Controls.Add方法添加到父窗体的panel中,并调用form.Show()方法显示子窗体。

在MainForm_Resize事件中,遍历panel中所有控件,设定控件的位置和锚定方式,以保证控件随着panel的变化而自适应。

最后,在button1_Click事件中,调用switchChildForm函数切换子窗体。

以上是实现子窗体自适应分辨率的基本操作,希望能对您有所帮助。

C#轻松实现界面布局随分辨率自动调整
可以参考下


https://www.cnblogs.com/Johnfx-home/p/16042852.html

可以使用布局管理器来让窗体和控件自适应大小和位置。可以通过设置控件的Anchor和Dock属性来实现。

对于动态添加子窗体,可以在按钮点击事件中创建新的窗体实例,然后根据当前主窗体的分辨率来设置新窗体的位置和大小。

先获取分辨率,然后根据分辨率来动态计算大小

用Anchor和Dock属性来自适应窗体和控件大小和位置,可以根据需要设置子窗体或控件的Anchor属性,使其能够根据主窗体或父控件的大小自动调整位置和大小

根据父窗口的大小,动态计算子窗口