【问题标题】:Form childs doesn't resize when form resize because of minimumsize由于最小尺寸,当表单调整大小时,表单子项不会调整大小
【发布时间】:2021-09-13 15:23:09
【问题描述】:

我有一个带有SplitContainer 的表单以填充码头。在拆分容器的面板 1 中,我有按钮,在面板 2 中,我在码头填充中有一个 UserControl。 panel2 中的 Usercontrol 类会根据在 panel1 中单击的按钮而变化,但会保持停靠填充。 每个用户控件都有一个最小尺寸。

每次更改 UC 以及移动拆分器时都会重新计算表单的 MinimumSize。这看起来非常好。

当我手动调整表单大小时,默认情况下一切都按照预期进行:很好。意思是,表格不能在最小尺寸值下调整大小。 当我手动移动拆分器时,默认情况下一切都按照预期进行:很好。意思是,面板 1 和面板 2 UC 调整大小以及所有子级。

但是,在任何给定时刻,如果表单处于最小尺寸并且我尝试移动滑块。表单调整大小以允许面板 2 UC 最小尺寸适合但 UC 不调整大小...

知道为什么以及如何解决它吗?

按照建议,我将应用程序简化到最低限度,这是 MainForm 的代码:

Public Class MainForm
  Private Sub SetMinSize()
    Dim borderWidth = Me.Width - Me.ClientSize.Width
    Me.MinimumSize = New Size(borderWidth + Me.SplitContainerMain.Panel1.Size.Width + Me.SplitContainerMain.SplitterWidth + Me.MainUserControl.MinimumSize.Width,
                              Me.MinimumSize.Height)
  End Sub

  Private Sub MainUserControl_ControlAdded(sender As Object, e As ControlEventArgs)
    Me.SetMinSize()
  End Sub

  Private Sub SplitContainerMain_SplitterMoved(sender As Object, e As SplitterEventArgs) Handles SplitContainerMain.SplitterMoved
    Me.SetMinSize()
  End Sub

  Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Me.SuspendLayout()
    Me.SplitContainerMain.Panel2.Controls.Remove(Me.MainUserControl)
    Try ' The try catch avoid error in case the handle is not created
      RemoveHandler Me.MainUserControl.ControlAdded, AddressOf Me.MainUserControl_ControlAdded
    Catch ex As Exception
    End Try
    Me.MainUserControl.Dispose()

    Me.MainUserControl = New UC1UserControl

    Me.MainUserControl.Dock = DockStyle.Fill
    Me.SplitContainerMain.Panel2.Controls.Add(Me.MainUserControl)
    AddHandler Me.MainUserControl.ControlAdded, AddressOf Me.MainUserControl_ControlAdded
    Me.ResumeLayout()

    Me.SetMinSize()
  End Sub

  Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    Me.SuspendLayout()
    Me.SplitContainerMain.Panel2.Controls.Remove(Me.MainUserControl)
    Try ' The try catch avoid error in case the handle is not created
      RemoveHandler Me.MainUserControl.ControlAdded, AddressOf Me.MainUserControl_ControlAdded
    Catch ex As Exception
    End Try
    Me.MainUserControl.Dispose()

    Me.MainUserControl = New UC2UserControl

    Me.MainUserControl.Dock = DockStyle.Fill
    Me.SplitContainerMain.Panel2.Controls.Add(Me.MainUserControl)
    AddHandler Me.MainUserControl.ControlAdded, AddressOf Me.MainUserControl_ControlAdded
    Me.ResumeLayout()

    Me.SetMinSize()
  End Sub
End Class

这是设计师:

<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
Partial Class MainForm
    Inherits System.Windows.Forms.Form

    'Form remplace la méthode Dispose pour nettoyer la liste des composants.
    <System.Diagnostics.DebuggerNonUserCode()>
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        Try
            If disposing AndAlso components IsNot Nothing Then
                components.Dispose()
            End If
        Finally
            MyBase.Dispose(disposing)
        End Try
    End Sub

    'Requise par le Concepteur Windows Form
    Private components As System.ComponentModel.IContainer

    'REMARQUE : la procédure suivante est requise par le Concepteur Windows Form
    'Elle peut être modifiée à l'aide du Concepteur Windows Form.  
    'Ne la modifiez pas à l'aide de l'éditeur de code.
    <System.Diagnostics.DebuggerStepThrough()>
    Private Sub InitializeComponent()
    Me.SplitContainerMain = New System.Windows.Forms.SplitContainer()
        Me.Button2 = New System.Windows.Forms.Button()
        Me.Button1 = New System.Windows.Forms.Button()
    Me.MainUserControl = New UserControl()
    CType(Me.SplitContainerMain, System.ComponentModel.ISupportInitialize).BeginInit()
        Me.SplitContainerMain.Panel1.SuspendLayout()
        Me.SplitContainerMain.Panel2.SuspendLayout()
        Me.SplitContainerMain.SuspendLayout()
        Me.SuspendLayout()
        '
        'SplitContainerMain
        '
        Me.SplitContainerMain.Dock = System.Windows.Forms.DockStyle.Fill
        Me.SplitContainerMain.FixedPanel = System.Windows.Forms.FixedPanel.Panel1
        Me.SplitContainerMain.Location = New System.Drawing.Point(0, 0)
        Me.SplitContainerMain.Name = "SplitContainerMain"
        '
        'SplitContainerMain.Panel1
        '
        Me.SplitContainerMain.Panel1.Controls.Add(Me.Button2)
        Me.SplitContainerMain.Panel1.Controls.Add(Me.Button1)
        Me.SplitContainerMain.Panel1MinSize = 170
        '
        'SplitContainerMain.Panel2
        '
        Me.SplitContainerMain.Panel2.Controls.Add(Me.MainUserControl)
        Me.SplitContainerMain.Panel2MinSize = 0
        Me.SplitContainerMain.Size = New System.Drawing.Size(784, 561)
        Me.SplitContainerMain.SplitterDistance = 170
        Me.SplitContainerMain.TabIndex = 0
        '
        'Button2
        '
        Me.Button2.Location = New System.Drawing.Point(40, 110)
        Me.Button2.Name = "Button2"
        Me.Button2.Size = New System.Drawing.Size(75, 23)
        Me.Button2.TabIndex = 1
        Me.Button2.Text = "Button2"
        Me.Button2.UseVisualStyleBackColor = True
        '
        'Button1
        '
        Me.Button1.Location = New System.Drawing.Point(40, 41)
        Me.Button1.Name = "Button1"
        Me.Button1.Size = New System.Drawing.Size(75, 23)
        Me.Button1.TabIndex = 0
        Me.Button1.Text = "Button1"
        Me.Button1.UseVisualStyleBackColor = True
        '
        'MainUserControl
        '
        Me.MainUserControl.Dock = System.Windows.Forms.DockStyle.Fill
        Me.MainUserControl.Location = New System.Drawing.Point(0, 0)
        Me.MainUserControl.Name = "MainUserControl"
        Me.MainUserControl.Size = New System.Drawing.Size(610, 561)
        Me.MainUserControl.TabIndex = 0
        '
        'MainForm
        '
        Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
        Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
        Me.AutoSize = True
        Me.ClientSize = New System.Drawing.Size(784, 561)
        Me.Controls.Add(Me.SplitContainerMain)
        Me.MinimumSize = New System.Drawing.Size(800, 600)
        Me.Name = "MainForm"
        Me.Tag = ""
        Me.Text = "Demo"
        Me.SplitContainerMain.Panel1.ResumeLayout(False)
        Me.SplitContainerMain.Panel2.ResumeLayout(False)
        CType(Me.SplitContainerMain, System.ComponentModel.ISupportInitialize).EndInit()
        Me.SplitContainerMain.ResumeLayout(False)
        Me.ResumeLayout(False)

    End Sub

    Friend WithEvents SplitContainerMain As SplitContainer
  Friend WithEvents MainUserControl As UserControl
  Friend WithEvents Button2 As Button
    Friend WithEvents Button1 As Button
End Class

这是一些屏幕截图:

UC1UserControl displayed correctly

UC2UserControl displayed correctly

UC2UserControl after spliter moved

UC1UserControl 和 UC2UserControl 中终于没有代码了,除了一个 Label 和一个不同的背景色来识别 UC。

谢谢

【问题讨论】:

  • 您的代码中发生了太多事情,无法期望有人在他们的脑海中将其可视化(至少对我而言)。如果您在网站标准中包含一些代码(Minimal, Reproducible Example)会有所帮助。
  • 也许在处理示例之前,您可以记录正在处理的事件,例如调整大小事件,作为自己调试的一种方式。
  • 我已按照建议更新了我的问题,希望现在可以理解。
  • @jérémyCourbat 您可能还希望在您的MainForm.Designer.vb 文件中包含代码和/或表单外观的屏幕截图。
  • 是的,显然会有帮助^^

标签: vb.net winforms


【解决方案1】:

经过几个小时的测试、记录等... 我已经找到了解决方案。

我在子 SetMinSize 中添加了一行:

  Private Sub SetMinSize()
    Dim borderWidth = Me.Width - Me.ClientSize.Width
    Me.MinimumSize = New Size(borderWidth + Me.SplitContainerMain.Panel1.Size.Width + Me.SplitContainerMain.SplitterWidth + Me.MainUserControl.MinimumSize.Width,
                              borderHeight + Me.MainUserControl.MinimumSize.Height)
    Me.SplitContainerMain.Panel2.Size = Me.MainUserControl.Size
  End Sub

现在它可以工作了。显然,在移动拆分器时,SplitContainer 的右侧面板(SplitContainerMain.Panel2)在调整表单大小后没有调整大小。

【讨论】:

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