(initial guess at nested proved to be incorrect. Problem seems to be that SplitContainer panels do not scale their hosted controls properly.)
I have some forms that have tab controls that fail to resize properly at load time. https://support.microsoft.com/en-us/kb/953934 describes such a kernel bug in 2008. Hard to believe it hasn't been fixed. I think it went away for a while but I'm beginning to see problems again.
The controls are nested pretty deep. Midi Parent, child form, tab control, splitter control with two panels and controls. For the top down the first control with the problem is the tab control. It resizes when the form is resized after loading but the anchors are incorrect and part of the control is clipped.
The problem seems to be specific to 100% desktop font size - desktops with 100+ size work OK. I develop at 125% using VS 2013 v5 - the issue was present on v4 as well.
Anyone know of a work around short of the custom control as outlined in the KB article?
Something else going on I've missed?
Looking at it more closely the SplitContainer is the control not resizing/honoring the anchors.
I tried running this code after the tab was shown and it didn't work - looks about the same as using anchors. It seems that the TabControl is reporting an incorrect ClientSize
SplitContainer1.Width = TabControl1.ClientSize.Width - 10
SplitContainer1.Height = TabControl1.ClientSize.Height - TabControl1.ItemSize.Height - 10
Here is a complete form that shows the problem. On a 125% desktop it shows as in the IDE on a 100% desktop the controls on the tab are not positioned properly.
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class frmChild
Inherits System.Windows.Forms.Form
'Form overrides dispose to clean up the component list.
<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
'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
Me.TabControl1 = New System.Windows.Forms.TabControl()
Me.TabPage1 = New System.Windows.Forms.TabPage()
Me.SplitContainer1 = New System.Windows.Forms.SplitContainer()
Me.Button1 = New System.Windows.Forms.Button()
Me.TabPage2 = New System.Windows.Forms.TabPage()
Me.TextBox1 = New System.Windows.Forms.TextBox()
Me.Button2 = New System.Windows.Forms.Button()
Me.TabControl1.SuspendLayout()
Me.TabPage1.SuspendLayout()
CType(Me.SplitContainer1, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SplitContainer1.Panel1.SuspendLayout()
Me.SplitContainer1.Panel2.SuspendLayout()
Me.SplitContainer1.SuspendLayout()
Me.SuspendLayout()
'
'TabControl1
'
Me.TabControl1.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _
Or System.Windows.Forms.AnchorStyles.Left) _
Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
Me.TabControl1.Controls.Add(Me.TabPage1)
Me.TabControl1.Controls.Add(Me.TabPage2)
Me.TabControl1.Location = New System.Drawing.Point(82, 2)
Me.TabControl1.Name = "TabControl1"
Me.TabControl1.SelectedIndex = 0
Me.TabControl1.Size = New System.Drawing.Size(466, 436)
Me.TabControl1.TabIndex = 2
'
'TabPage1
'
Me.TabPage1.Controls.Add(Me.SplitContainer1)
Me.TabPage1.Location = New System.Drawing.Point(4, 25)
Me.TabPage1.Name = "TabPage1"
Me.TabPage1.Padding = New System.Windows.Forms.Padding(3)
Me.TabPage1.Size = New System.Drawing.Size(458, 407)
Me.TabPage1.TabIndex = 0
Me.TabPage1.Text = "TabPage1"
Me.TabPage1.UseVisualStyleBackColor = True
'
'SplitContainer1
'
Me.SplitContainer1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
Me.SplitContainer1.Dock = System.Windows.Forms.DockStyle.Fill
Me.SplitContainer1.Location = New System.Drawing.Point(3, 3)
Me.SplitContainer1.Name = "SplitContainer1"
Me.SplitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal
'
'SplitContainer1.Panel1
'
Me.SplitContainer1.Panel1.Controls.Add(Me.Button2)
Me.SplitContainer1.Panel1.Controls.Add(Me.TextBox1)
'
'SplitContainer1.Panel2
'
Me.SplitContainer1.Panel2.Controls.Add(Me.Button1)
Me.SplitContainer1.Size = New System.Drawing.Size(452, 401)
Me.SplitContainer1.SplitterDistance = 223
Me.SplitContainer1.TabIndex = 0
'
'Button1
'
Me.Button1.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
Me.Button1.Location = New System.Drawing.Point(371, 146)
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
'
'TabPage2
'
Me.TabPage2.Location = New System.Drawing.Point(4, 25)
Me.TabPage2.Name = "TabPage2"
Me.TabPage2.Padding = New System.Windows.Forms.Padding(3)
Me.TabPage2.Size = New System.Drawing.Size(854, 450)
Me.TabPage2.TabIndex = 1
Me.TabPage2.Text = "TabPage2"
Me.TabPage2.UseVisualStyleBackColor = True
'
'TextBox1
'
Me.TextBox1.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _
Or System.Windows.Forms.AnchorStyles.Left) _
Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
Me.TextBox1.BackColor = System.Drawing.SystemColors.Info
Me.TextBox1.Location = New System.Drawing.Point(17, 13)
Me.TextBox1.Multiline = True
Me.TextBox1.Name = "TextBox1"
Me.TextBox1.ScrollBars = System.Windows.Forms.ScrollBars.Vertical
Me.TextBox1.Size = New System.Drawing.Size(344, 177)
Me.TextBox1.TabIndex = 0
'
'Button2
'
Me.Button2.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
Me.Button2.Location = New System.Drawing.Point(371, 195)
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
'
'frmChild
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(120.0!, 120.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi
Me.ClientSize = New System.Drawing.Size(548, 439)
Me.Controls.Add(Me.TabControl1)
Me.Name = "frmChild"
Me.Text = "frmChild"
Me.TabControl1.ResumeLayout(False)
Me.TabPage1.ResumeLayout(False)
Me.SplitContainer1.Panel1.ResumeLayout(False)
Me.SplitContainer1.Panel1.PerformLayout()
Me.SplitContainer1.Panel2.ResumeLayout(False)
CType(Me.SplitContainer1, System.ComponentModel.ISupportInitialize).EndInit()
Me.SplitContainer1.ResumeLayout(False)
Me.ResumeLayout(False)
End Sub
Friend WithEvents TabControl1 As System.Windows.Forms.TabControl
Friend WithEvents TabPage1 As System.Windows.Forms.TabPage
Friend WithEvents SplitContainer1 As System.Windows.Forms.SplitContainer
Friend WithEvents Button1 As System.Windows.Forms.Button
Friend WithEvents TabPage2 As System.Windows.Forms.TabPage
Friend WithEvents Button2 As System.Windows.Forms.Button
Friend WithEvents TextBox1 As System.Windows.Forms.TextBox
End Class
If the SplitPanel
isn't anchoring its contents correctly, you could try putting the contents into another container that is less buggy.
Try putting a TableLayoutPanel
inside the SplitPanel
. Set the TableLayoutPanel.Dock
property to Fill
, and then .Anchor
your controls inside that. (Don't use .Dock
inside a TableLayoutPanel
, it's a bit flaky).
The controls inside the TableLayoutPanel
will have new properties called .RowSpan
and .ColumnSpan
which allow the controls to span multiple cells.
There is a little arrow in the top right of the TableLayoutPanel
that will allow you to edit the rows and columns. I find the best is to make as many as possible fixed width/height and then use percentage for the rest. I don't use Autosize
but you could try that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With