如果 Control.Hide 则不会崩溃
No collapse if Control.Hide
我想使用 TableLayoutPanel 和 FlowLayoutPanel 的 AutoSize 来布局我的控件。在布置好父控件后,我想冻结布局,这样如果我隐藏一个控件,就不会折叠任何东西。所以我想使用 Control.Visible 但不折叠它。
背景资料:我有一个支持多种语言的控件。我希望设计能够自动适应语言。如果我单击一个 CheckBox,有时某些控件会隐藏或显示,如果我使用 AutoSize,这会导致整个设计发生变化。我不希望控件折叠,我只希望控件显示父控件的背景并保持大小。
示例 (vb.net)
Form1.vb
Public Class Form1
Private Sub CheckBox1_CheckedChanged(sender As Object, e As EventArgs) Handles CheckBox1.CheckedChanged
Label1.Visible = CheckBox1.Checked
End Sub
End Class
Form1.Designer.vb
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class Form1
Inherits System.Windows.Forms.Form
'Das Formular überschreibt den Löschvorgang, um die Komponentenliste zu bereinigen.
<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
'Wird vom Windows Form-Designer benötigt.
Private components As System.ComponentModel.IContainer
'Hinweis: Die folgende Prozedur ist für den Windows Form-Designer erforderlich.
'Das Bearbeiten ist mit dem Windows Form-Designer möglich.
'Das Bearbeiten mit dem Code-Editor ist nicht möglich.
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
Me.TableLayoutPanel1 = New System.Windows.Forms.TableLayoutPanel()
Me.Label1 = New System.Windows.Forms.Label()
Me.CheckBox1 = New System.Windows.Forms.CheckBox()
Me.TableLayoutPanel1.SuspendLayout()
Me.SuspendLayout()
'
'TableLayoutPanel1
'
Me.TableLayoutPanel1.AutoSize = True
Me.TableLayoutPanel1.ColumnCount = 1
Me.TableLayoutPanel1.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle())
Me.TableLayoutPanel1.Controls.Add(Me.Label1, 0, 0)
Me.TableLayoutPanel1.Controls.Add(Me.CheckBox1, 0, 1)
Me.TableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill
Me.TableLayoutPanel1.Location = New System.Drawing.Point(0, 0)
Me.TableLayoutPanel1.Name = "TableLayoutPanel1"
Me.TableLayoutPanel1.RowCount = 2
Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle())
Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle())
Me.TableLayoutPanel1.Size = New System.Drawing.Size(800, 450)
Me.TableLayoutPanel1.TabIndex = 0
'
'Label1
'
Me.Label1.AutoSize = True
Me.Label1.Location = New System.Drawing.Point(3, 0)
Me.Label1.Name = "Label1"
Me.Label1.Size = New System.Drawing.Size(39, 13)
Me.Label1.TabIndex = 0
Me.Label1.Text = "Label1"
'
'CheckBox1
'
Me.CheckBox1.AutoSize = True
Me.CheckBox1.Checked = True
Me.CheckBox1.CheckState = System.Windows.Forms.CheckState.Checked
Me.CheckBox1.Location = New System.Drawing.Point(3, 16)
Me.CheckBox1.Name = "CheckBox1"
Me.CheckBox1.Size = New System.Drawing.Size(81, 17)
Me.CheckBox1.TabIndex = 1
Me.CheckBox1.Text = "CheckBox1"
Me.CheckBox1.UseVisualStyleBackColor = True
'
'Form1
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.AutoSize = True
Me.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink
Me.ClientSize = New System.Drawing.Size(800, 450)
Me.Controls.Add(Me.TableLayoutPanel1)
Me.Name = "Form1"
Me.Text = "Form1"
Me.TableLayoutPanel1.ResumeLayout(False)
Me.TableLayoutPanel1.PerformLayout()
Me.ResumeLayout(False)
Me.PerformLayout()
End Sub
Friend WithEvents TableLayoutPanel1 As TableLayoutPanel
Friend WithEvents Label1 As Label
Friend WithEvents CheckBox1 As CheckBox
End Class
结果:
我希望控件不会四处移动。如果隐藏标签,我希望控件保持大小。标签不应折叠,而应绘制父控件的背景。
我比较满意的最佳解决方案是编写我自己的自定义面板来实现所需的行为,并将目标控件放入该自定义面板中。诀窍是在我的自定义面板中添加一个普通面板,如果 Visible 更改为 false,它会隐藏目标控件。
VB.NET
中的解决方案
NoCollapsePanel.vb
Public Class NoCollapsePanel
Public Enum VisibleModeE
Collapse
KeepSize
End Enum
Public Property VisibleMode As VisibleModeE
Get
Return _VisibleMode
End Get
Set
If Value = VisibleMode Then Return
_VisibleMode = Value
RefreshVisibility()
End Set
End Property
Private Sub RefreshVisibility()
If _Visible Then Controls.Remove(hidePanel)
Select Case VisibleMode
Case VisibleModeE.Collapse
MyBase.Visible = _Visible
Case VisibleModeE.KeepSize
MyBase.Visible = True
If Not Visible Then
' this is doing the trick
hidePanel.Size = Size
Controls.Add(hidePanel)
hidePanel.BringToFront()
End If
End Select
End Sub
Public Shadows Event VisibleChanged As EventHandler
Private ReadOnly hidePanel As New Panel() With {.Margin = New Padding(0)}
Private _Visible As Boolean = True
Private _VisibleMode As VisibleModeE = VisibleModeE.KeepSize
Public Overloads Property Visible As Boolean
Get
Return _Visible
End Get
Set
If _Visible = Value Then Return
_Visible = Value
RefreshVisibility()
RaiseEvent VisibleChanged(Me, New EventArgs())
End Set
End Property
Protected Overrides Sub OnResize(eventargs As EventArgs)
MyBase.OnResize(eventargs)
hidePanel.Size = Size
End Sub
End Class
NoCollapsePanel.Designer.vb
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class NoCollapsePanel
Inherits System.Windows.Forms.Panel
'Das Steuerelement überschreibt den Löschvorgang zum Bereinigen der Komponentenliste.
<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
'Wird vom Steuerelement-Designer benötigt.
Private components As System.ComponentModel.IContainer
' Hinweis: Die folgende Prozedur ist für den Komponenten-Designer erforderlich.
' Sie kann mit dem Komponenten-Designer geändert werden. Das Bearbeiten mit
' dem Code-Editor ist nicht möglich.
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
components = New System.ComponentModel.Container()
End Sub
End Class
测试面板
Form1.vb
Public Class Form1
Public Sub New()
' Dieser Aufruf ist für den Designer erforderlich.
InitializeComponent()
' Fügen Sie Initialisierungen nach dem InitializeComponent()-Aufruf hinzu.
ComboBox1.DataSource = System.Enum.GetValues(GetType(NoCollapsePanel.VisibleModeE))
End Sub
Private Sub CheckBox1_CheckedChanged(sender As Object, e As EventArgs) Handles CheckBox1.CheckedChanged
NoCollapsePanel1.Visible = CheckBox1.Checked
End Sub
Private rnd As New Random
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
BackColor = Color.FromArgb(255, rnd.Next(255), rnd.Next(255), rnd.Next(255))
End Sub
Private Sub CheckBox2_CheckedChanged(sender As Object, e As EventArgs) Handles CheckBox2.CheckedChanged
Label1.Text = If(CheckBox2.Checked, "some text", "some very very very very long text")
End Sub
Private Sub NoCollapsePanel1_VisibleChanged(sender As Object, e As EventArgs) Handles NoCollapsePanel1.VisibleChanged
TestVisibleChanged_Label.Text = DateTime.Now
End Sub
Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
NoCollapsePanel1.VisibleMode = ComboBox1.SelectedValue
End Sub
End Class
Form1.Designer.vb
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class Form1
Inherits System.Windows.Forms.Form
'Das Formular überschreibt den Löschvorgang, um die Komponentenliste zu bereinigen.
<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
'Wird vom Windows Form-Designer benötigt.
Private components As System.ComponentModel.IContainer
'Hinweis: Die folgende Prozedur ist für den Windows Form-Designer erforderlich.
'Das Bearbeiten ist mit dem Windows Form-Designer möglich.
'Das Bearbeiten mit dem Code-Editor ist nicht möglich.
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
Me.TableLayoutPanel1 = New System.Windows.Forms.TableLayoutPanel()
Me.CheckBox1 = New System.Windows.Forms.CheckBox()
Me.Button1 = New System.Windows.Forms.Button()
Me.CheckBox2 = New System.Windows.Forms.CheckBox()
Me.TestVisibleChanged_Label = New System.Windows.Forms.Label()
Me.FlowLayoutPanel2 = New System.Windows.Forms.FlowLayoutPanel()
Me.ComboBox1 = New System.Windows.Forms.ComboBox()
Me.NoCollapsePanel1 = New WindowsApp4.NoCollapsePanel()
Me.FlowLayoutPanel1 = New System.Windows.Forms.FlowLayoutPanel()
Me.Label1 = New System.Windows.Forms.Label()
Me.TableLayoutPanel1.SuspendLayout()
Me.FlowLayoutPanel2.SuspendLayout()
Me.NoCollapsePanel1.SuspendLayout()
Me.FlowLayoutPanel1.SuspendLayout()
Me.SuspendLayout()
'
'TableLayoutPanel1
'
Me.TableLayoutPanel1.AutoSize = True
Me.TableLayoutPanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink
Me.TableLayoutPanel1.ColumnCount = 1
Me.TableLayoutPanel1.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle())
Me.TableLayoutPanel1.Controls.Add(Me.NoCollapsePanel1, 0, 0)
Me.TableLayoutPanel1.Controls.Add(Me.CheckBox1, 0, 1)
Me.TableLayoutPanel1.Controls.Add(Me.Button1, 0, 2)
Me.TableLayoutPanel1.Controls.Add(Me.CheckBox2, 0, 3)
Me.TableLayoutPanel1.Controls.Add(Me.TestVisibleChanged_Label, 0, 4)
Me.TableLayoutPanel1.Controls.Add(Me.ComboBox1, 0, 5)
Me.TableLayoutPanel1.Location = New System.Drawing.Point(3, 3)
Me.TableLayoutPanel1.Name = "TableLayoutPanel1"
Me.TableLayoutPanel1.RowCount = 6
Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle())
Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle())
Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle())
Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle())
Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle())
Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle())
Me.TableLayoutPanel1.Size = New System.Drawing.Size(127, 134)
Me.TableLayoutPanel1.TabIndex = 1
'
'CheckBox1
'
Me.CheckBox1.AutoSize = True
Me.CheckBox1.Checked = True
Me.CheckBox1.CheckState = System.Windows.Forms.CheckState.Checked
Me.CheckBox1.Location = New System.Drawing.Point(3, 22)
Me.CheckBox1.Name = "CheckBox1"
Me.CheckBox1.Size = New System.Drawing.Size(83, 17)
Me.CheckBox1.TabIndex = 1
Me.CheckBox1.Text = "Show Panel"
Me.CheckBox1.UseVisualStyleBackColor = True
'
'Button1
'
Me.Button1.AutoSize = True
Me.Button1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink
Me.Button1.Location = New System.Drawing.Point(3, 45)
Me.Button1.Name = "Button1"
Me.Button1.Size = New System.Drawing.Size(106, 23)
Me.Button1.TabIndex = 2
Me.Button1.Text = "Change BackColor"
Me.Button1.UseVisualStyleBackColor = True
'
'CheckBox2
'
Me.CheckBox2.AutoSize = True
Me.CheckBox2.Location = New System.Drawing.Point(3, 74)
Me.CheckBox2.Name = "CheckBox2"
Me.CheckBox2.Size = New System.Drawing.Size(92, 17)
Me.CheckBox2.TabIndex = 3
Me.CheckBox2.Text = "Change Label"
Me.CheckBox2.UseVisualStyleBackColor = True
'
'TestVisibleChanged_Label
'
Me.TestVisibleChanged_Label.AutoSize = True
Me.TestVisibleChanged_Label.Location = New System.Drawing.Point(3, 94)
Me.TestVisibleChanged_Label.Name = "TestVisibleChanged_Label"
Me.TestVisibleChanged_Label.Size = New System.Drawing.Size(88, 13)
Me.TestVisibleChanged_Label.TabIndex = 4
Me.TestVisibleChanged_Label.Text = "Visibility changed"
'
'FlowLayoutPanel2
'
Me.FlowLayoutPanel2.AutoSize = True
Me.FlowLayoutPanel2.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink
Me.FlowLayoutPanel2.Controls.Add(Me.TableLayoutPanel1)
Me.FlowLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill
Me.FlowLayoutPanel2.Location = New System.Drawing.Point(0, 0)
Me.FlowLayoutPanel2.Name = "FlowLayoutPanel2"
Me.FlowLayoutPanel2.Size = New System.Drawing.Size(800, 450)
Me.FlowLayoutPanel2.TabIndex = 2
'
'ComboBox1
'
Me.ComboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
Me.ComboBox1.FormattingEnabled = True
Me.ComboBox1.Location = New System.Drawing.Point(3, 110)
Me.ComboBox1.Name = "ComboBox1"
Me.ComboBox1.Size = New System.Drawing.Size(121, 21)
Me.ComboBox1.TabIndex = 5
'
'NoCollapsePanel1
'
Me.NoCollapsePanel1.AutoSize = True
Me.NoCollapsePanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink
Me.NoCollapsePanel1.Controls.Add(Me.FlowLayoutPanel1)
Me.NoCollapsePanel1.Location = New System.Drawing.Point(3, 3)
Me.NoCollapsePanel1.Name = "NoCollapsePanel1"
Me.NoCollapsePanel1.Size = New System.Drawing.Size(45, 13)
Me.NoCollapsePanel1.TabIndex = 0
Me.NoCollapsePanel1.VisibleMode = WindowsApp4.NoCollapsePanel.VisibleModeE.KeepSize
'
'FlowLayoutPanel1
'
Me.FlowLayoutPanel1.AutoSize = True
Me.FlowLayoutPanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink
Me.FlowLayoutPanel1.Controls.Add(Me.Label1)
Me.FlowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill
Me.FlowLayoutPanel1.Location = New System.Drawing.Point(0, 0)
Me.FlowLayoutPanel1.Name = "FlowLayoutPanel1"
Me.FlowLayoutPanel1.Size = New System.Drawing.Size(45, 13)
Me.FlowLayoutPanel1.TabIndex = 1
'
'Label1
'
Me.Label1.AutoSize = True
Me.Label1.Location = New System.Drawing.Point(3, 0)
Me.Label1.Name = "Label1"
Me.Label1.Size = New System.Drawing.Size(39, 13)
Me.Label1.TabIndex = 0
Me.Label1.Text = "Label1"
'
'Form1
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.AutoSize = True
Me.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink
Me.ClientSize = New System.Drawing.Size(800, 450)
Me.Controls.Add(Me.FlowLayoutPanel2)
Me.Name = "Form1"
Me.Text = "Form1"
Me.TableLayoutPanel1.ResumeLayout(False)
Me.TableLayoutPanel1.PerformLayout()
Me.FlowLayoutPanel2.ResumeLayout(False)
Me.FlowLayoutPanel2.PerformLayout()
Me.NoCollapsePanel1.ResumeLayout(False)
Me.NoCollapsePanel1.PerformLayout()
Me.FlowLayoutPanel1.ResumeLayout(False)
Me.FlowLayoutPanel1.PerformLayout()
Me.ResumeLayout(False)
Me.PerformLayout()
End Sub
Friend WithEvents NoCollapsePanel1 As NoCollapsePanel
Friend WithEvents Label1 As Label
Friend WithEvents FlowLayoutPanel1 As FlowLayoutPanel
Friend WithEvents TableLayoutPanel1 As TableLayoutPanel
Friend WithEvents CheckBox1 As CheckBox
Friend WithEvents FlowLayoutPanel2 As FlowLayoutPanel
Friend WithEvents Button1 As Button
Friend WithEvents CheckBox2 As CheckBox
Friend WithEvents TestVisibleChanged_Label As Label
Friend WithEvents ComboBox1 As ComboBox
End Class
我想使用 TableLayoutPanel 和 FlowLayoutPanel 的 AutoSize 来布局我的控件。在布置好父控件后,我想冻结布局,这样如果我隐藏一个控件,就不会折叠任何东西。所以我想使用 Control.Visible 但不折叠它。
背景资料:我有一个支持多种语言的控件。我希望设计能够自动适应语言。如果我单击一个 CheckBox,有时某些控件会隐藏或显示,如果我使用 AutoSize,这会导致整个设计发生变化。我不希望控件折叠,我只希望控件显示父控件的背景并保持大小。
示例 (vb.net)
Form1.vb
Public Class Form1
Private Sub CheckBox1_CheckedChanged(sender As Object, e As EventArgs) Handles CheckBox1.CheckedChanged
Label1.Visible = CheckBox1.Checked
End Sub
End Class
Form1.Designer.vb
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class Form1
Inherits System.Windows.Forms.Form
'Das Formular überschreibt den Löschvorgang, um die Komponentenliste zu bereinigen.
<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
'Wird vom Windows Form-Designer benötigt.
Private components As System.ComponentModel.IContainer
'Hinweis: Die folgende Prozedur ist für den Windows Form-Designer erforderlich.
'Das Bearbeiten ist mit dem Windows Form-Designer möglich.
'Das Bearbeiten mit dem Code-Editor ist nicht möglich.
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
Me.TableLayoutPanel1 = New System.Windows.Forms.TableLayoutPanel()
Me.Label1 = New System.Windows.Forms.Label()
Me.CheckBox1 = New System.Windows.Forms.CheckBox()
Me.TableLayoutPanel1.SuspendLayout()
Me.SuspendLayout()
'
'TableLayoutPanel1
'
Me.TableLayoutPanel1.AutoSize = True
Me.TableLayoutPanel1.ColumnCount = 1
Me.TableLayoutPanel1.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle())
Me.TableLayoutPanel1.Controls.Add(Me.Label1, 0, 0)
Me.TableLayoutPanel1.Controls.Add(Me.CheckBox1, 0, 1)
Me.TableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill
Me.TableLayoutPanel1.Location = New System.Drawing.Point(0, 0)
Me.TableLayoutPanel1.Name = "TableLayoutPanel1"
Me.TableLayoutPanel1.RowCount = 2
Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle())
Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle())
Me.TableLayoutPanel1.Size = New System.Drawing.Size(800, 450)
Me.TableLayoutPanel1.TabIndex = 0
'
'Label1
'
Me.Label1.AutoSize = True
Me.Label1.Location = New System.Drawing.Point(3, 0)
Me.Label1.Name = "Label1"
Me.Label1.Size = New System.Drawing.Size(39, 13)
Me.Label1.TabIndex = 0
Me.Label1.Text = "Label1"
'
'CheckBox1
'
Me.CheckBox1.AutoSize = True
Me.CheckBox1.Checked = True
Me.CheckBox1.CheckState = System.Windows.Forms.CheckState.Checked
Me.CheckBox1.Location = New System.Drawing.Point(3, 16)
Me.CheckBox1.Name = "CheckBox1"
Me.CheckBox1.Size = New System.Drawing.Size(81, 17)
Me.CheckBox1.TabIndex = 1
Me.CheckBox1.Text = "CheckBox1"
Me.CheckBox1.UseVisualStyleBackColor = True
'
'Form1
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.AutoSize = True
Me.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink
Me.ClientSize = New System.Drawing.Size(800, 450)
Me.Controls.Add(Me.TableLayoutPanel1)
Me.Name = "Form1"
Me.Text = "Form1"
Me.TableLayoutPanel1.ResumeLayout(False)
Me.TableLayoutPanel1.PerformLayout()
Me.ResumeLayout(False)
Me.PerformLayout()
End Sub
Friend WithEvents TableLayoutPanel1 As TableLayoutPanel
Friend WithEvents Label1 As Label
Friend WithEvents CheckBox1 As CheckBox
End Class
结果:
我希望控件不会四处移动。如果隐藏标签,我希望控件保持大小。标签不应折叠,而应绘制父控件的背景。
我比较满意的最佳解决方案是编写我自己的自定义面板来实现所需的行为,并将目标控件放入该自定义面板中。诀窍是在我的自定义面板中添加一个普通面板,如果 Visible 更改为 false,它会隐藏目标控件。
VB.NET
中的解决方案NoCollapsePanel.vb
Public Class NoCollapsePanel
Public Enum VisibleModeE
Collapse
KeepSize
End Enum
Public Property VisibleMode As VisibleModeE
Get
Return _VisibleMode
End Get
Set
If Value = VisibleMode Then Return
_VisibleMode = Value
RefreshVisibility()
End Set
End Property
Private Sub RefreshVisibility()
If _Visible Then Controls.Remove(hidePanel)
Select Case VisibleMode
Case VisibleModeE.Collapse
MyBase.Visible = _Visible
Case VisibleModeE.KeepSize
MyBase.Visible = True
If Not Visible Then
' this is doing the trick
hidePanel.Size = Size
Controls.Add(hidePanel)
hidePanel.BringToFront()
End If
End Select
End Sub
Public Shadows Event VisibleChanged As EventHandler
Private ReadOnly hidePanel As New Panel() With {.Margin = New Padding(0)}
Private _Visible As Boolean = True
Private _VisibleMode As VisibleModeE = VisibleModeE.KeepSize
Public Overloads Property Visible As Boolean
Get
Return _Visible
End Get
Set
If _Visible = Value Then Return
_Visible = Value
RefreshVisibility()
RaiseEvent VisibleChanged(Me, New EventArgs())
End Set
End Property
Protected Overrides Sub OnResize(eventargs As EventArgs)
MyBase.OnResize(eventargs)
hidePanel.Size = Size
End Sub
End Class
NoCollapsePanel.Designer.vb
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class NoCollapsePanel
Inherits System.Windows.Forms.Panel
'Das Steuerelement überschreibt den Löschvorgang zum Bereinigen der Komponentenliste.
<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
'Wird vom Steuerelement-Designer benötigt.
Private components As System.ComponentModel.IContainer
' Hinweis: Die folgende Prozedur ist für den Komponenten-Designer erforderlich.
' Sie kann mit dem Komponenten-Designer geändert werden. Das Bearbeiten mit
' dem Code-Editor ist nicht möglich.
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
components = New System.ComponentModel.Container()
End Sub
End Class
测试面板
Form1.vb
Public Class Form1
Public Sub New()
' Dieser Aufruf ist für den Designer erforderlich.
InitializeComponent()
' Fügen Sie Initialisierungen nach dem InitializeComponent()-Aufruf hinzu.
ComboBox1.DataSource = System.Enum.GetValues(GetType(NoCollapsePanel.VisibleModeE))
End Sub
Private Sub CheckBox1_CheckedChanged(sender As Object, e As EventArgs) Handles CheckBox1.CheckedChanged
NoCollapsePanel1.Visible = CheckBox1.Checked
End Sub
Private rnd As New Random
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
BackColor = Color.FromArgb(255, rnd.Next(255), rnd.Next(255), rnd.Next(255))
End Sub
Private Sub CheckBox2_CheckedChanged(sender As Object, e As EventArgs) Handles CheckBox2.CheckedChanged
Label1.Text = If(CheckBox2.Checked, "some text", "some very very very very long text")
End Sub
Private Sub NoCollapsePanel1_VisibleChanged(sender As Object, e As EventArgs) Handles NoCollapsePanel1.VisibleChanged
TestVisibleChanged_Label.Text = DateTime.Now
End Sub
Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
NoCollapsePanel1.VisibleMode = ComboBox1.SelectedValue
End Sub
End Class
Form1.Designer.vb
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class Form1
Inherits System.Windows.Forms.Form
'Das Formular überschreibt den Löschvorgang, um die Komponentenliste zu bereinigen.
<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
'Wird vom Windows Form-Designer benötigt.
Private components As System.ComponentModel.IContainer
'Hinweis: Die folgende Prozedur ist für den Windows Form-Designer erforderlich.
'Das Bearbeiten ist mit dem Windows Form-Designer möglich.
'Das Bearbeiten mit dem Code-Editor ist nicht möglich.
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
Me.TableLayoutPanel1 = New System.Windows.Forms.TableLayoutPanel()
Me.CheckBox1 = New System.Windows.Forms.CheckBox()
Me.Button1 = New System.Windows.Forms.Button()
Me.CheckBox2 = New System.Windows.Forms.CheckBox()
Me.TestVisibleChanged_Label = New System.Windows.Forms.Label()
Me.FlowLayoutPanel2 = New System.Windows.Forms.FlowLayoutPanel()
Me.ComboBox1 = New System.Windows.Forms.ComboBox()
Me.NoCollapsePanel1 = New WindowsApp4.NoCollapsePanel()
Me.FlowLayoutPanel1 = New System.Windows.Forms.FlowLayoutPanel()
Me.Label1 = New System.Windows.Forms.Label()
Me.TableLayoutPanel1.SuspendLayout()
Me.FlowLayoutPanel2.SuspendLayout()
Me.NoCollapsePanel1.SuspendLayout()
Me.FlowLayoutPanel1.SuspendLayout()
Me.SuspendLayout()
'
'TableLayoutPanel1
'
Me.TableLayoutPanel1.AutoSize = True
Me.TableLayoutPanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink
Me.TableLayoutPanel1.ColumnCount = 1
Me.TableLayoutPanel1.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle())
Me.TableLayoutPanel1.Controls.Add(Me.NoCollapsePanel1, 0, 0)
Me.TableLayoutPanel1.Controls.Add(Me.CheckBox1, 0, 1)
Me.TableLayoutPanel1.Controls.Add(Me.Button1, 0, 2)
Me.TableLayoutPanel1.Controls.Add(Me.CheckBox2, 0, 3)
Me.TableLayoutPanel1.Controls.Add(Me.TestVisibleChanged_Label, 0, 4)
Me.TableLayoutPanel1.Controls.Add(Me.ComboBox1, 0, 5)
Me.TableLayoutPanel1.Location = New System.Drawing.Point(3, 3)
Me.TableLayoutPanel1.Name = "TableLayoutPanel1"
Me.TableLayoutPanel1.RowCount = 6
Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle())
Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle())
Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle())
Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle())
Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle())
Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle())
Me.TableLayoutPanel1.Size = New System.Drawing.Size(127, 134)
Me.TableLayoutPanel1.TabIndex = 1
'
'CheckBox1
'
Me.CheckBox1.AutoSize = True
Me.CheckBox1.Checked = True
Me.CheckBox1.CheckState = System.Windows.Forms.CheckState.Checked
Me.CheckBox1.Location = New System.Drawing.Point(3, 22)
Me.CheckBox1.Name = "CheckBox1"
Me.CheckBox1.Size = New System.Drawing.Size(83, 17)
Me.CheckBox1.TabIndex = 1
Me.CheckBox1.Text = "Show Panel"
Me.CheckBox1.UseVisualStyleBackColor = True
'
'Button1
'
Me.Button1.AutoSize = True
Me.Button1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink
Me.Button1.Location = New System.Drawing.Point(3, 45)
Me.Button1.Name = "Button1"
Me.Button1.Size = New System.Drawing.Size(106, 23)
Me.Button1.TabIndex = 2
Me.Button1.Text = "Change BackColor"
Me.Button1.UseVisualStyleBackColor = True
'
'CheckBox2
'
Me.CheckBox2.AutoSize = True
Me.CheckBox2.Location = New System.Drawing.Point(3, 74)
Me.CheckBox2.Name = "CheckBox2"
Me.CheckBox2.Size = New System.Drawing.Size(92, 17)
Me.CheckBox2.TabIndex = 3
Me.CheckBox2.Text = "Change Label"
Me.CheckBox2.UseVisualStyleBackColor = True
'
'TestVisibleChanged_Label
'
Me.TestVisibleChanged_Label.AutoSize = True
Me.TestVisibleChanged_Label.Location = New System.Drawing.Point(3, 94)
Me.TestVisibleChanged_Label.Name = "TestVisibleChanged_Label"
Me.TestVisibleChanged_Label.Size = New System.Drawing.Size(88, 13)
Me.TestVisibleChanged_Label.TabIndex = 4
Me.TestVisibleChanged_Label.Text = "Visibility changed"
'
'FlowLayoutPanel2
'
Me.FlowLayoutPanel2.AutoSize = True
Me.FlowLayoutPanel2.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink
Me.FlowLayoutPanel2.Controls.Add(Me.TableLayoutPanel1)
Me.FlowLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill
Me.FlowLayoutPanel2.Location = New System.Drawing.Point(0, 0)
Me.FlowLayoutPanel2.Name = "FlowLayoutPanel2"
Me.FlowLayoutPanel2.Size = New System.Drawing.Size(800, 450)
Me.FlowLayoutPanel2.TabIndex = 2
'
'ComboBox1
'
Me.ComboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
Me.ComboBox1.FormattingEnabled = True
Me.ComboBox1.Location = New System.Drawing.Point(3, 110)
Me.ComboBox1.Name = "ComboBox1"
Me.ComboBox1.Size = New System.Drawing.Size(121, 21)
Me.ComboBox1.TabIndex = 5
'
'NoCollapsePanel1
'
Me.NoCollapsePanel1.AutoSize = True
Me.NoCollapsePanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink
Me.NoCollapsePanel1.Controls.Add(Me.FlowLayoutPanel1)
Me.NoCollapsePanel1.Location = New System.Drawing.Point(3, 3)
Me.NoCollapsePanel1.Name = "NoCollapsePanel1"
Me.NoCollapsePanel1.Size = New System.Drawing.Size(45, 13)
Me.NoCollapsePanel1.TabIndex = 0
Me.NoCollapsePanel1.VisibleMode = WindowsApp4.NoCollapsePanel.VisibleModeE.KeepSize
'
'FlowLayoutPanel1
'
Me.FlowLayoutPanel1.AutoSize = True
Me.FlowLayoutPanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink
Me.FlowLayoutPanel1.Controls.Add(Me.Label1)
Me.FlowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill
Me.FlowLayoutPanel1.Location = New System.Drawing.Point(0, 0)
Me.FlowLayoutPanel1.Name = "FlowLayoutPanel1"
Me.FlowLayoutPanel1.Size = New System.Drawing.Size(45, 13)
Me.FlowLayoutPanel1.TabIndex = 1
'
'Label1
'
Me.Label1.AutoSize = True
Me.Label1.Location = New System.Drawing.Point(3, 0)
Me.Label1.Name = "Label1"
Me.Label1.Size = New System.Drawing.Size(39, 13)
Me.Label1.TabIndex = 0
Me.Label1.Text = "Label1"
'
'Form1
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.AutoSize = True
Me.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink
Me.ClientSize = New System.Drawing.Size(800, 450)
Me.Controls.Add(Me.FlowLayoutPanel2)
Me.Name = "Form1"
Me.Text = "Form1"
Me.TableLayoutPanel1.ResumeLayout(False)
Me.TableLayoutPanel1.PerformLayout()
Me.FlowLayoutPanel2.ResumeLayout(False)
Me.FlowLayoutPanel2.PerformLayout()
Me.NoCollapsePanel1.ResumeLayout(False)
Me.NoCollapsePanel1.PerformLayout()
Me.FlowLayoutPanel1.ResumeLayout(False)
Me.FlowLayoutPanel1.PerformLayout()
Me.ResumeLayout(False)
Me.PerformLayout()
End Sub
Friend WithEvents NoCollapsePanel1 As NoCollapsePanel
Friend WithEvents Label1 As Label
Friend WithEvents FlowLayoutPanel1 As FlowLayoutPanel
Friend WithEvents TableLayoutPanel1 As TableLayoutPanel
Friend WithEvents CheckBox1 As CheckBox
Friend WithEvents FlowLayoutPanel2 As FlowLayoutPanel
Friend WithEvents Button1 As Button
Friend WithEvents CheckBox2 As CheckBox
Friend WithEvents TestVisibleChanged_Label As Label
Friend WithEvents ComboBox1 As ComboBox
End Class