Cascade MdiChildren

时间:2014-01-06 16:53:54

标签: vb.net winforms linq

我正在尝试为加载的子窗口执行窗口级联。我无法使用LayoutMdi(),因为它会更改子表单大小。

我可以使用父母的MdiChildren

这样做
    Dim i As Integer
    For Each frm As Form In Me.MdiChildren
        frm.Location = New Point(i, i)
        frm.BringToFront()
        i += 30
    Next

但是该顺序是由于加载顺序。我可以排序。打开窗户的顶部,但我宁愿使用Z顺序。如何在给定父级中确定表单的Z顺序?

另一个传递同样的问题 - 试图获得一个排序的'列表'(另一个数据结构可能更好?)或表格排序.Top:

    Dim childForms As New List(Of Form)
    For Each frm As Form In Me.MdiChildren
        childForms.Add(frm)
    Next
    Dim sortedChildForms As Form() =
        From entry In childForms
        Order By DirectCast(entry.Top, Integer)
        Ascending Select entry

我是Linq的新手,所以我真的不知道我在这里做什么。 DirectCast失败,因为Int不支持Int)。我尝试使用order by entry.Top,但失败了:

    System.InvalidCastException was unhandled
    Message=Unable to cast object of type 
     WhereSelectEnumerableIterator`2[System.Windows.Forms.Form,
     System.Windows.Forms.Form]' 
     to type 'System.Windows.Forms.Form[]'.

有两个问题:我可以获取MdiChild表单的ZOrder吗?如何通过.Top或.Z对结果'列表'进行排序?

请不要只回答C#,因为在这种情况下它们不会自动转换为VB.Net。

1 个答案:

答案 0 :(得分:0)

这需要pinvoke,您必须使用GetWindow() function枚举Z顺序中的子项。基本方案是找到最后一个MDI子窗口,底部的窗口,然后继续工作。这段代码效果很好:

Private Sub CascadeButton_Click(sender As Object, e As EventArgs) Handles CascadeButton.Click
    Dim pos As Integer = 0
    If Me.MdiChildren.Count = 0 Then Exit Sub
    '' Find the child on the bottom
    Dim child = GetWindow(Me.MdiChildren(0).Handle, GW_HWNDLAST)
    Do While child <> IntPtr.Zero
        Form.FromHandle(child).Location = New Point(pos, pos)
        pos += 30
        '' Find the next on above it
        child = GetWindow(child, GW_HWNDPREV)
    Loop
End Sub

Private Const GW_HWNDLAST As Integer = 1
Private Const GW_HWNDPREV As Integer = 3
Private Declare Function GetWindow Lib "User32.dll" (hwnd As IntPtr, cmd As Integer) As IntPtr