2014-01-12 3 views
0

Хорошо, чтобы дать вам большую картину здесь; У меня есть список, который отображает записи из базы данных, я хочу изменить размер как списка, так и окна формы относительно количества строк, содержащихся в списке. Просто.Изменение размера формы Окно делает форму Исчезновение

Вот мой код, который швы, чтобы форма исчезла - обратите внимание, что программа по-прежнему работает со значком, но без видимой формы вообще.

frmMain является формой окна, которая содержит ListView - это высота 228.

lvRec является ListView - это высота 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 

их в настоящее время 3 строки в ListView, но этот код делает форма исчезает, хотя я заявил в expand247

+0

Использование Jing для записи видео и связать его здесь - это бесплатное программное обеспечение. Не совсем понятно, что вы имеете в виду. – Neolisk

+0

Это для вашего отладчика. Установите точку останова на 'If i = 3 Then' и шаг за шагом введите код. Изучите свойства 'frmMain.Height' и' frmMain.lvRec.Height'. –

ответ

0

Рассмотрим текущий код:

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

Может frmMain.Height когда-нибудь стать больше или равен 247, если вы всегда установить его в +1?

+0

Привет, у меня создается впечатление, что «+1» должен увеличивать текущий размер формы на 1 каждый раз, когда он зацикливается ... – user2980316

+1

Неправильное впечатление. '+ 1' совпадает с' 1'. Возможно, вы имели в виду 'frmMain.Height = frmMain.Height + 1' или' frmMain.Height + = 1' –

+0

Да, только что открыли его '+ = 1', я обновил свой код, и у меня, похоже, есть аналогичная проблема до, я обновлю это, когда я выясню, что сейчас происходит :) – user2980316

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.Height началась в 103 ... Это будет уменьшает на 1 навсегда, то есть основной поток пользовательского интерфейса будет заперты и форма никогда не будет перерисовывать.

Лучше (но все еще несовершенный) пример будет ...

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 секунды (2000 мс) 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 

Это дает вам приятный линейный переход.

Стоит отметить, что формы окон (иначе WinForms) особенно вредны для такого рода вещей. Довольно часто пользовательский интерфейс не будет обновляться, если используется основной (UI) поток. Есть способы обойти это с помощью DoEvents, но в лучшем случае они взломаны, поэтому, если вы не реализуете какую-то фоновый поток, пользовательский интерфейс скорее всего закроется до тех пор, пока вы не закончите свой цикл (вот почему ваша форма исчезла - это было изменение размера навсегда и не получило возможности перерисовать).

Существует несколько альтернатив. 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 
Смежные вопросы