【问题标题】:Re-Arrange Panels After Hiding One VB.Net隐藏一个 VB.Net 后重新排列面板
【发布时间】:2012-07-18 17:21:50
【问题描述】:

我创建了一个非常复杂的 Windows 窗体应用程序。我现在要做的是,如果单击不同的按钮以禁用某些面板,但将其下方的所有其他面板向上移动,使其看起来井井有条。我很难受。我想开发一个函数,它传入一个被禁用的面板以及它下面的所有其他面板的列表,并使用递归重新排列所有面板。此功能有效,但它没有考虑一个面板的高度是否大于另一个面板的高度,它会在两个面板之间留下额外的空间。任何帮助将非常感激。

Public Sub whatever(ByVal panel As Panel, ByVal list As List(Of Panel))
    Dim temppanel As Panel = New Panel()
    For Each item As Panel In list
        temppanel.Location = New Point(temppanel.Location.X, item.Location.Y)
        item.Location = New Point(item.Location.X, panel.Location.Y)
        list.Remove(item)
        whatever(temppanel, list)
        If list.Count = 0 Then
            Exit For
        End If
    Next
End Sub

图片

http://imageshack.us/photo/my-images/268/panelsz.png/

【问题讨论】:

  • 屏幕截图可能有助于解释这里发生了什么。关于初始化该列表,您如何首先调用此 whatever 函数?
  • 每当单击特定按钮时都会调用“whatever”函数。基于一个按钮,我知道不再显示哪个面板。我然后循环并找到面板下不再显示的所有面板,然后将所有这些面板存储到一个列表中,然后我调用任何具有不再显示的面板的函数以及所有其他面板的列表需要移动的面板。我希望这回答了你的问题。
  • 当您说“下方”时,您是指在 z 顺序中的下方,还是位于屏幕上垂直“下方”位置的下方?此外,如果您所做的只是从中获取位置,请不要将 Panel 传递给您的函数,而是传递一个 Point(或 Rectangle,如果您需要所有坐标)。
  • 对不起,我的意思是屏幕上的垂直较低位置。
  • @tcarvin 因为我使用递归来执行此操作,所以我通过前一个面板来获取坐标。我真的不知道这样做的最佳方法是什么,任何帮助将不胜感激。

标签: vb.net winforms


【解决方案1】:

FlowLayoutPanel 可能更适合这个,但这里有一个通用的方法来做我认为你正在寻找的东西:

Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) _
                          Handles Button1.Click
  ToggelPanel(Panel2)
End Sub

Private Sub ToggelPanel(ByVal whichPanel As Panel)
  Dim startPoint As New Point(10, 10)
  whichPanel.Visible = Not whichPanel.Visible

  For Each pnl As Panel In Me.Controls.OfType(Of Panel)(). _
                           Where(Function(x) x.Visible). _
                           OrderBy(Function(x) x.TabIndex)
    pnl.Location = startPoint
    startPoint.Y += pnl.Height + 4
  Next
End Sub

如果这些面板不在Me 中,请将Me 替换为父容器。


如果在 LINQ 不可用的情况下使用 .net 2.0,该函数将如下所示:

Private Shared Function CompareTabIndex(ByVal p1 As Panel, ByVal p2 As Panel) _
                                        As Integer
  Return p1.TabIndex.CompareTo(p2.TabIndex)
End Function

Private Sub ToggelPanel(ByVal whichPanel As Panel)
  Dim startPoint As New Point(10, 10)
  whichPanel.Visible = Not whichPanel.Visible

  Dim panels As New List(Of Panel)
  For i As Integer = 0 To Me.Controls.Count - 1
    If TypeOf Me.Controls(i) Is Panel Then
      If Me.Controls(i).Visible Then
        panels.Add(Me.Controls(i))
      End If
    End If
  Next

  panels.Sort(New Comparison(Of Panel)(AddressOf CompareTabIndex))

  For Each pnl As Panel In panels
    pnl.Location = startPoint
    startPoint.Y += pnl.Height + pnl.Margin.Bottom
  Next
End Sub

【讨论】:

  • 嘿,非常感谢您的快速回答。您是否知道动态计算图像中每个面板之间间距的最佳方法,因为它们可能不一样?
  • @Nick 我随意选择了 4 个像素作为我的空间。如果你愿意,你可以增加它。什么决定了间距?我想您可以将每个面板的 Margin.Bottom 值设置为它需要的空间量,然后将其更改为 startPoint.Y += pnl.Height + pnl.Margin.Bottom
  • 这很好用,但我发现了一个问题。我正在更新的代码在 Framework 2.0 中,Linq 将不可用。 :( 这让我很生气。
  • @Nick 我添加了一个非 linq 版本。
猜你喜欢
  • 2016-08-17
  • 1970-01-01
  • 1970-01-01
  • 2019-05-07
  • 1970-01-01
  • 2013-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多