当属性绑定到设置时,奇怪的拆分容器行为



我有一个WinForms应用程序,它包含两个SplitContainer。第一个SplitContainer横跨整个窗体,其方向是水平的。第二个SplitContainer位于第一个拆分容器的左侧面板内,其方向是垂直的。我将每个拆分容器的SplitterDistance属性与应用程序设置绑定,以便在用户退出程序时保存位置。然而,这会引发一些奇怪的问题。如果拖动主拆分容器的位置,然后拖动第二个拆分容器的立场,则第一个拆分容器会跳回原始位置,并且不会保存该立场。如果我移除第二个拆分容器,一切都会正常工作。如果没有绑定SplitterDistance属性,我也看不到这个问题。

有人知道是什么原因造成的吗?或者我该怎么解决?

更新我现在还发现,如果从第二个拆分容器中删除属性绑定,一切都会正常工作。即使我手动尝试实现这一点(即,删除属性绑定并在SplitContainer2.SplitterMoved事件中添加My.Settings.sideDist=SplitContainer2.SplitterDistance),问题仍然存在。

我正在使用vb.net。

设计者生成的代码:

<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class Form1
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.SplitContainer1 = New System.Windows.Forms.SplitContainer()
Me.SplitContainer2 = New System.Windows.Forms.SplitContainer()
Me.ListBox1 = New System.Windows.Forms.ListBox()
Me.ListBox2 = New System.Windows.Forms.ListBox()
CType(Me.SplitContainer1, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SplitContainer1.Panel1.SuspendLayout()
Me.SplitContainer1.Panel2.SuspendLayout()
Me.SplitContainer1.SuspendLayout()
CType(Me.SplitContainer2, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SplitContainer2.Panel1.SuspendLayout()
Me.SplitContainer2.SuspendLayout()
Me.SuspendLayout()
'
'SplitContainer1
'
Me.SplitContainer1.DataBindings.Add(New System.Windows.Forms.Binding("SplitterDistance", Global.WindowsApplication1.My.MySettings.Default, "mainDist", True, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged))
Me.SplitContainer1.Dock = System.Windows.Forms.DockStyle.Fill
Me.SplitContainer1.Location = New System.Drawing.Point(0, 0)
Me.SplitContainer1.Name = "SplitContainer1"
'
'SplitContainer1.Panel1
'
Me.SplitContainer1.Panel1.Controls.Add(Me.SplitContainer2)
'
'SplitContainer1.Panel2
'
Me.SplitContainer1.Panel2.Controls.Add(Me.ListBox2)
Me.SplitContainer1.Size = New System.Drawing.Size(730, 413)
Me.SplitContainer1.SplitterDistance = Global.WindowsApplication1.My.MySettings.Default.mainDist
Me.SplitContainer1.TabIndex = 0
'
'SplitContainer2
'
Me.SplitContainer2.DataBindings.Add(New System.Windows.Forms.Binding("SplitterDistance", Global.WindowsApplication1.My.MySettings.Default, "sideDist", True, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged))
Me.SplitContainer2.Dock = System.Windows.Forms.DockStyle.Fill
Me.SplitContainer2.Location = New System.Drawing.Point(0, 0)
Me.SplitContainer2.Name = "SplitContainer2"
Me.SplitContainer2.Orientation = System.Windows.Forms.Orientation.Horizontal
'
'SplitContainer2.Panel1
'
Me.SplitContainer2.Panel1.Controls.Add(Me.ListBox1)
Me.SplitContainer2.Size = New System.Drawing.Size(310, 413)
Me.SplitContainer2.SplitterDistance = Global.WindowsApplication1.My.MySettings.Default.sideDist
Me.SplitContainer2.TabIndex = 0
'
'ListBox1
'
Me.ListBox1.Dock = System.Windows.Forms.DockStyle.Fill
Me.ListBox1.FormattingEnabled = True
Me.ListBox1.Location = New System.Drawing.Point(0, 0)
Me.ListBox1.Name = "ListBox1"
Me.ListBox1.Size = New System.Drawing.Size(310, 49)
Me.ListBox1.TabIndex = 0
'
'ListBox2
'
Me.ListBox2.Dock = System.Windows.Forms.DockStyle.Fill
Me.ListBox2.FormattingEnabled = True
Me.ListBox2.Location = New System.Drawing.Point(0, 0)
Me.ListBox2.Name = "ListBox2"
Me.ListBox2.Size = New System.Drawing.Size(416, 413)
Me.ListBox2.TabIndex = 0
'
'Form1
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(730, 413)
Me.Controls.Add(Me.SplitContainer1)
Me.Name = "Form1"
Me.Text = "Form1"
Me.SplitContainer1.Panel1.ResumeLayout(False)
Me.SplitContainer1.Panel2.ResumeLayout(False)
CType(Me.SplitContainer1, System.ComponentModel.ISupportInitialize).EndInit()
Me.SplitContainer1.ResumeLayout(False)
Me.SplitContainer2.Panel1.ResumeLayout(False)
CType(Me.SplitContainer2, System.ComponentModel.ISupportInitialize).EndInit()
Me.SplitContainer2.ResumeLayout(False)
Me.ResumeLayout(False)
End Sub
Friend WithEvents SplitContainer1 As System.Windows.Forms.SplitContainer
Friend WithEvents ListBox2 As System.Windows.Forms.ListBox
Friend WithEvents SplitContainer2 As System.Windows.Forms.SplitContainer
Friend WithEvents ListBox1 As System.Windows.Forms.ListBox
End Class

虽然我建议不要通过设计器文件设置SplitContainerDataBindings属性(该属性没有向设计器公开是有原因的),但真正的问题是应用程序设置没有得到更新。当用户修改SplitterDistance时,一切都很好,但是当控制无效时,将从初始值没有改变的设置中重新读取并应用设置。简单的解决方案是将新值保存回设置中。以下代码应该足够了:

''' <summary>
''' Sets the mainDist application setting to the new SplitterDistance
''' </summary>
''' <remarks>http://stackoverflow.com/users/2659234/brandon-b</remarks>
Private Sub SplitContainer1_SplitterMoved(sender As SplitContainer, e As SplitterEventArgs) Handles SplitContainer1.SplitterMoved
Global.WindowsApplication1.My.MySettings.Default.mainDist = sender.SplitterDistance
End Sub
''' <summary>
''' Sets the sideDist application setting to the new SplitterDistance
''' </summary>
''' <remarks>http://stackoverflow.com/users/2659234/brandon-b</remarks>
Private Sub SplitContainer2_SplitterMoved(sender As SplitContainer, e As SplitterEventArgs) Handles SplitContainer2.SplitterMoved
Global.WindowsApplication1.My.MySettings.Default.sideDist = sender.SplitterDistance
End Sub

旧主题,但我能够通过将拆分器的位置记录为拆分容器高度的小数来解决这个SplitContainer错误(?)。所以我的Settings Save()方法看起来是这样的:

Properties.Settings.Default.VertSplitterDistance = (decimal)VertSplitContainer.SplitterDistance / (decimal)VertSplitContainer.Width;
Properties.Settings.Default.Save();

并在初始化表单后,加载应用程序上的设置启动:

VertSplitContainer.SplitterDistance = (int)Math.Round(Properties.Settings.Default.HorizontalSplitterDistance * HorizontalSplitContainer.Height, 0);

(这是C#,但应该很容易转换为vb.net…)

相关内容

  • 没有找到相关文章

最新更新