2013-02-08 5 views
1

У меня есть программа Winform, которая выполняет некоторые вычисления, когда пользователь нажимает на кнопку, а затем вызывает событие paintbox для рисования нового BMP на основе результатов расчеты. Это прекрасно работает.Текст метки не обновляется до тех пор, пока весь цикл не будет завершен.

Теперь я хочу сделать это в 100 раз, и каждый раз, когда PictureBox обновляется, я хочу видеть итерацию, что это в настоящее время, обновляя текст на этикетке в соответствии с ниже:

private void button2_Click(object sender, EventArgs e) 
     { 

     for (int iterations = 1; iterations <= 100; iterations++) 
     { 
      // do some calculations to change the cellmap parameters 
      cellMap.Calculate(); 

      // Refresh picturebox1 
      pictureBox1.Invalidate(); 
      pictureBox1.Update(); 

      // Update label with the current iteration number 
      label1.Text = iterations.ToString(); 
     } 
    } 

    private void pictureBox1_Paint(object sender, PaintEventArgs e) 
    { 

     Bitmap bmp = new Bitmap(cellMap.Dimensions.Width, cellMap.Dimensions.Height); 
     Graphics gBmp = Graphics.FromImage(bmp); 

     int rectWidth = scaleFactor; 
     int rectHeight = scaleFactor; 

     // Create solid brushes 
     Brush blueBrush = new SolidBrush(Color.Blue); 
     Brush greenBrush = new SolidBrush(Color.Green); 
     Brush transparentBrush = new SolidBrush(Color.Transparent); 

     Graphics g = e.Graphics; 

     for (int i = 0; i < cellMap.Dimensions.Width; i++) 
     { 
       for (int j = 0; j < cellMap.Dimensions.Height; j++) 
       { 
        // retrieve the rectangle and draw it 
        Brush whichBrush; 

        if (cellMap.GetCell(i, j).CurrentState == CellState.State1) 
        { 
         whichBrush = blueBrush; 
        } 
        else if (cellMap.GetCell(i, j).CurrentState == CellState.State2) 
        { 
         whichBrush = greenBrush; 
        } 
        else 
        { 
         whichBrush = transparentBrush; 
        } 

        // draw rectangle to bmp 
        gBmp.FillRectangle(whichBrush, i, j, 1f, 1f); 
       } 
     } 

     g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor; 
     g.DrawImage(bmp, 0, 0, pictureBox1.Width, pictureBox1.Height); 
    } 

Проблема У меня есть то, что текст ярлыка будет отображаться только после завершения последнего обновления. По существу, он не отображает от 1 до 99. Я могу видеть обновления ящика после каждого обновления, поскольку BMP изменяется с каждой итерацией. Есть идеи?

+0

Вы пытались вызвать 'label1.Invalidate();' или/и 'label1.Update();' после изменения текста? – horgh

+0

Нет, но после добавления этих двух утверждений он начал работать. Однако я не понимаю, почему? – deutschZuid

+0

Попробуйте прочитать этот [Method.Update Method] (http://msdn.microsoft.com/en-us/library/system.windows.forms.control.update.aspx) – horgh

ответ

4

Чтобы ответить на ваш вопрос, почему вы должны это сделать: Программы Windows Forms запускают все в одном потоке - поток пользовательского интерфейса. Это означает, что он должен выполнять код по порядку, чтобы он завершил функцию, прежде чем он сможет вернуться к UI-коду. Другими словами, он не может обновлять фотографии до тех пор, пока их не закончит функция, поэтому, если вы обновите изображение 100 раз, только последний будет обновляться. Использование кода Invalidate/Update сообщает компилятору «приостановить» выполнение функции и заставляет ее обновлять интерфейс, а не ждать до конца функции. Надеюсь, это поможет!

+0

Да, спасибо. Он делает +1 – FrostyFire

+0

То же самое касается и других элементов управления на форме (в данном случае, на этикетке) ... это имеет смысл, я думаю. – deutschZuid

6
// Code fragement... 
// 5 cent solution, add Invalidate/Update 
label1.Text = iterations.ToString(); 
label1.Invalidate(); 
label1.Update(); 
+1

Зачем это поможет? Поясните свой ответ. – FrostyFire

+1

Привет, Джон. Это работает. Фактически я решил использовать метку полосы состояния вместо этого, и это было немного сложнее, поскольку метки полосы не имеют собственного метода обновления. В итоге я назвал метод обновления родительского контейнера. toolStripStatusLabel1.Invalidate(); statusStrip1.Update(); – deutschZuid

+0

Почему я должен был это сделать? Я не совсем понимаю ... – deutschZuid

Смежные вопросы