【发布时间】:2015-04-09 16:19:00
【问题描述】:
我有一个嵌入了FlowLayoutPanel 的自定义控件,我在其中添加了元素(其他自定义控件)。在FlowLayoutPanel 的布局事件中,我将FlowLayoutPanel 中的所有控件调整为包含FlowLayoutPanel 的大小。
在需要垂直滚动条 (AutoScroll = True) 之前一切正常,占用 FLpanel 内的空间,导致出现水平滚动条。
你看到的乱码是我在元素的构造函数中生成的一些随机占位符文本。
我想防止这种情况发生:
我尝试向用户控件添加一个垂直滚动控件并在Scroll 事件中执行FlowLayoutPanel.VertScroll.Value=sender.value:它似乎有效,但是在移动滚动条时使实际的垂直和水平滚动条闪烁(出现和消失)很多控制。
我真的不知道是否有一些属性可以使滚动条在FlowLayoutPanel控件内容之外。
我在 VB.Net 中执行此操作,但 C# 答案很好(因为它基本上是相同的语法,至少在使用控件和 UI 时)。
编辑
我忘了提到我在FlowLayoutPanel 中有WrapContents=false 和AutoScroll=true。
另外,如果你觉得这个设计很熟悉:它是 Opera M2 邮件列表屏幕的像素完美副本。
更新 1
在你的 cmets 之后,我想出了这个:
Public Class FlowListPanel ' The user control
Private Sub Me_Load(sender As Object, e As EventArgs) Handles Me.Load
FL_Panel.AutoScroll = True ' FL_Panel is the FlowLayoutPanel
FL_Panel.WrapContents = False
FL_Panel.Dock = System.Windows.Forms.DockStyle.Fill
FL_Panel.FlowDirection = System.Windows.Forms.FlowDirection.TopDown
FL_Panel.Margin = New System.Windows.Forms.Padding(0)
End Sub
Sub AddItem(c As Control)
FL_Panel.Controls.Add(c)
ReorderControls()
End Sub
Private Sub FLP_CSC(sender As Object, e As EventArgs) Handles FL_Panel.ClientSizeChanged
ReorderControls()
End Sub
Sub ReorderControls()
For Each ctrl In FL_Panel.Controls
ctrl.Width = FL_Panel.ClientSize.Width
Next
End Sub
Private Sub FL_Panel_L(sender As Object, e As LayoutEventArgs) Handles FL_Panel.Layout
ReorderControls()
End Sub
End Class
似乎可以,但是当达到垂直滚动条出现的临界点时,出现水平滚动条出现问题。
一旦添加了另一个项目,水平滚动条就会消失。
另外,我认为问题可能是由于ReorderControls sub 没有被调用,所以我做了一个按钮来调用它,但没有任何改变。
移除元素时不会出现此问题(但仅在添加时出现)。
在调整窗口大小并且必须出现垂直滚动条时也会发生这种情况。
如下所示,添加新元素后,它可以正常工作:
更新 2
我已遵循 Plutonix 的建议(修改代码 from his other answer),因此我对 ReorderControls 子进行了一些修改,以这种方式:
Sub ReorderControls()
Dim HScrollVis As Boolean = NativeMethods.IsHScrollVisible(FL_Panel)
If HScrollVis Then ' HScroll visible -> kill it with fire!
NativeMethods.ShowHideScrollBar(FL_Panel,
NativeMethods.SBOrientation.SB_HORZ,
False)
Return ' as it works anyway...
End If
For Each ctrl In FL_Panel.Controls
ctrl.Width = FL_Panel.ClientSize.Width
Next
End Sub
现在水平滚动条闪烁一次,而不是停留在那里,当垂直滚动条出现时。
我喜欢 gif,所以这是目前的效果:
您可能看不到(由于 gif 的低帧率),水平条可能只有在几分之一秒内寻找它的人才能注意到。
我认为问题已解决 80%,并将继续前进。如果我或某人提出明确的建议,我会立即接受答案。
【问题讨论】:
-
您需要扩展控件以获得更多水平空间。只需减少文本和字体之间的一些空白,您就有足够的空间可以利用。不要让它变得比需要的更难
-
您是否尝试过使用 Windows Messaging / WinProc 执行此操作..?这是一个例子stackoverflow.com/questions/16009743/…
-
如果您不想要 HScroll,则需要缩小事物的宽度,以便它们和 VScroll 适合。如果您不喜欢显示的间隙/BG,您可以在
ClientSizeChanged事件中添加代码,并在它发生变化时缩小它们(弹出时似乎只有 6 个)。您还可以添加一些 PInvokes 来吃掉 HScroll,这样它就不会在添加第 7 个时弹出然后消失。 OTOH,这也许可以作为自定义控件内置到它们中? -
@JeremyK 我正在考虑它,但我不知道如何获取滚动条的大小,也不知道什么事件是合适的(现在我知道了,谢谢 tp Plutonix)。