当属性绑定到设置时奇怪的拆分容器行为 [英] Strange split container behavior when properties are bound to settings
问题描述
我有一个包含两个 SplitContainer 的 WinForms 应用程序.第一个 SplitContainer 跨越整个表单并且它的方向是水平的.第二个 SplitContainer 位于第一个拆分容器的左侧面板内,其方向是垂直的.我将每个拆分容器的 SplitterDistance 属性与应用程序设置绑定,以便在用户退出程序时保存位置.然而,这会导致奇怪的问题.如果我拖动主拆分容器的位置,然后拖动第二个拆分容器的位置,则第一个拆分容器会跳回原始位置,并且不保存该位置.如果我删除第二个拆分容器,一切正常.如果未绑定 SplitterDistance 属性,我也看不到此问题.
I have a WinForms application that contains two SplitContainers. The first SplitContainer spans the entire form and its orientation is horizontal. The second SplitContainer is within the left panel of the first split container and its orientation is vertical. I bound each split container's SplitterDistance property with an application setting so that the position will be saved when the user quits the program. However, this causes strange problems. If I drag the main split container's position and then drag the second split container's position, the first split container jumps back to the original position and the position is not saved. If I remove the second split container everything works fine. I also don't see this problem if the SplitterDistance property is not bound.
有人知道是什么原因造成的,或者我该如何解决吗?
Does anybody know what is causing this or how I can fix it?
更新我现在也想通了,如果我从第二个拆分容器中删除属性绑定,一切正常.即使我手动尝试实现这一点(即移除属性绑定并在 SplitContainer2.SplitterMoved 事件中添加 My.Settings.sideDist = SplitContainer2.SplitterDistance),问题仍然存在.
Update I also figured out now if I remove the property binding from the second split container everything works fine. Even if I manually try to implement this (that is, removing the property binding and add My.Settings.sideDist = SplitContainer2.SplitterDistance in the SplitContainer2.SplitterMoved event), the problem is still present.
我正在使用 vb.net.
I am using 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
推荐答案
虽然我建议不要通过设计器文件设置 SplitContainer
的 DataBindings
属性(有一些原因)为什么该属性没有暴露给设计者),真正的问题是应用程序设置没有得到更新.当用户修改 SplitterDistance
时一切正常,但是当控件失效时,设置被重新读取并从初始值没有改变的设置中应用.简单的解决方案是将新值保存回设置.以下代码应该足够了:
While I advise not setting the DataBindings
property of a SplitContainer
via the designer file (there are reasons why that property is not exposed to the designer), the real issue is that the application settings are not getting updated. When the user modifies the SplitterDistance
all is well, however when the control becomes invalidated, the setting is re-read and applied from the settings which have not changed from their initial value. The simple solution is to save the new value back to the settings. the following code should suffice for you:
''' <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
这篇关于当属性绑定到设置时奇怪的拆分容器行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!