调整窗体大小窗口使窗体消失

时间:2014-01-12 21:37:19

标签: vb.net

好的,在这里给你更大的图片;我有一个列表视图,显示数据库中的记录,我想改变列表框和窗体窗口的大小相对于listview包含的行数。简单。

这是我的代码,接缝使表单消失 - 注意程序仍然以图标运行,但根本没有可见的形式。

frmMain是包含列表视图的窗体 - 它的高度为228。

lvRec是列表视图 - 它的高度为85。

此代码存储在文件中,并在表单

需要时调用
Public Sub Resizer() 



'Count records/rows with data
       Dim i As Integer
                i = frmMain.lvRec.Items.Count

'Set window Size
     If i = 3 Then
        If frmMain.Height < 247 Then
            Do Until frmMain.Height = 247
                frmMain.Height = +1
                System.Threading.Thread.Sleep(100)
            Loop
            Do Until frmMain.lvRec.Height = 104
                frmMain.Height = +1
                System.Threading.Thread.Sleep(100)
            Loop
        ElseIf frmMain.Height > 247 Then
            Do Until frmMain.Height = 247
                frmMain.Height = -1
                System.Threading.Thread.Sleep(100)
            Loop
            Do Until frmMain.lvRec.Height = 104
                frmMain.lvRec.Height = -1
                System.Threading.Thread.Sleep(100)
            Loop
        End If

它们目前在listview中有3行,但是这段代码使表格消失,即使我已经说明要扩展247

2 个答案:

答案 0 :(得分:0)

考虑您当前的代码:

Do Until frmMain.Height = 247
                frmMain.Height = +1
                System.Threading.Thread.Sleep(100)
            Loop

如果您始终将frmMain.Height设置为+1,{{1}}是否会变得大于或等于247?

答案 1 :(得分:0)

我怀疑你的代码陷入无限循环。

通过你的例子......

假设i = 3 ...

 If i = 3 Then
    If frmMain.Height < 247 Then
        ' Most likely > 247 as that's a very small height. Let's skip on for now...
    ElseIf frmMain.Height > 247 Then
        'Else would suffice - not need for ElseIf as it ignores the case  frmMain.Height = 247
        Do Until frmMain.Height = 247
            'Shrink form height (very slowly - we're talking pixels here)
            frmMain.Height = -1 'Not correct as discussed in the other answer and below
            System.Threading.Thread.Sleep(100)
        Loop
        Do Until frmMain.lvRec.Height = 104
            ' Who says frmMain.lvRec.Height is > 104? It may well be less in which case this loop will never end. See note below.
            frmMain.lvRec.Height = -1
            System.Threading.Thread.Sleep(100)
        Loop
    End If

一般情况下,只有当你某些时,才会尝试在逻辑条件下使用精确值。

想象一下frmMain.lvRec.Height103开始的场景......它会永远减少1,这意味着主UI线程将被锁定,表单永远不会重绘。

更好(但仍然不完美)的例子是......

While frmMain.lvRec.Height <> 104
    If frmMain.lvRec.Height > 104
        frmMain.lvRec.Height -= 1 'Same as  frmMain.lvRec.Height = frmMain.lvRec.Height -1
    Else
        frmMain.lvRec.Height += 1 'vice-versa
    End If
    System.Threading.Thread.Sleep(100)
End While

理想情况下,您希望大小的转换需要一段固定的时间。假设它应该持续2秒(2,000毫秒),步长为100毫秒= 20步......

Dim Current = frmMain.lvRec.Height
Dim Desired = 104
For i = 1 to 20 '1 to 20 since we're aiming for exactly 20 steps. Normally a for would start at 0 but in this case that would cause 21 steps
    Dim Pos = Desired * (i/20) + Current * ((20-i)/20)
    frmMain.lvRec.Height = Pos
    System.Threading.Thread.Sleep(100)
End While

我们在这里做的是创建一个非常简单的线性'缓和'。有效地获取旧值的百分比和随时间变化的新值的百分比(随着i增加)

示例...当前值= 200,期望值= 100,共20步(中间值显示在[]中,以使其更易于理解)...

SizeThisLoop = Desired * (i/20) + Current * ((20-i)/20)

100 * (01/20) [=05] + 200 * (19/20) [=190] = 195
100 * (02/20) [=10] + 200 * (18/20) [=180] = 190
...
100 * (05/20) [=25] + 200 * (15/20) [=150] = 175
...
100 * (20/20) [=100] + 200 * (0/20) [=000] = 100

这为您提供了一个很好的线性过渡。

值得注意的是,Windows窗体(又名WinForms)在这种情况下特别糟糕。如果主(UI)线程正在使用,用户界面通常不会更新。有很多方法可以使用DoEvents,但它们最好是黑客 - 所以除非你实现某种形式的背景线程,否则UI很可能会锁定,直到你完成循环(这就是为什么你的表单消失了 - 它正在永远调整大小并且没有机会重绘。

有几种选择。 WPF在设计时考虑到了很好的效果,但行为方式完全不同,无法以这种方式编写。

如果不这样做,后台线程的使用会有所帮助 - 后台线程会随着时间的推移调整大小并告诉前台线程尽可能调整窗口大小。

像...一样的东西。

Public Sub Resizer()
    'Set up a background thread to do the resizing
    Dim T As New Threading.Thread(Sub() ResizeWorker())
    T.Start()
End Sub


Private Sub ResizeWorker()
    'The background thread. Takes approx 2 seconds to complete
    Dim Current = frmMain.lvRec.Height
    Dim Desired = 104
    For i = 1 to 20 '1 to 20 since we're aiming for exactly 20 steps. Normally a for would start at 0 but in this case that would cause 21 steps
        Dim Pos = Desired * (i/20) + Current * ((20-i)/20)
        UIResize(Cint(Pos)) 'Do a resize
        System.Threading.Thread.Sleep(100)
    End While
End Sub


Private Sub UIResize(NewSize As Integer)
    'Only the UI thread is allowed to update controls. Check if we're allowed to do so? (Can we make a change without invoking another thread?)
    If Me.InvokeRequired
        'This code isn't being executed on the UI thread. Ask the UI thread to run this method with the same parameters when it when it can
        Me.Invoke(Sub() UIResize(NewSize))
    Else
        'We're now running on the UI thread... Resize at will!
        Me.lvRec.Height = NewSize
    End IF
End Sub