2010-02-18 7 views
19

У меня есть код, который позволяет перетаскивать форму без полей в winforms, которые я использую уже несколько месяцев, что работает очень хорошо.Invalidate vs Update

Но когда мне впервые был предоставлен код, они использовали this.Invalidate(); в событии формы MouseMove, и форма слегка мерцала и была медленной при перетаскивании. Итак, я заменил Invalidate() на Update() в событии MouseMove, и, к моему удивлению, теперь форму можно перетаскивать очень плавно и не мерцает вообще.

Может ли кто-нибудь объяснить мне, почему Update делает код более эффективным, чем Invalidate, даже если Invalidate звучит так, как будто он правильный?

Спасибо :)

P.S. Может быть, это поможет больше, если я добавлю код ... Добавьте его сейчас.

Редактировать - Вот код:


private void titlebar_MouseDown(object sender, MouseEventArgs e) 
{ 
    this.IsMouseDown = true; 

    this.LastCursorPosition = new Point(e.X, e.Y); 

    if (this.BackColor == Color.White) 
    { 
     this.BackColor = Color.GhostWhite; 
     tbox.BackColor = Color.GhostWhite; 
     tbox.ForeColor = Color.Black; 
    } 
    else 
    { 
     this.BackColor = Color.FromArgb(20, 20, 20); 
     tbox.BackColor = Color.FromArgb(20, 20, 20); 
     tbox.ForeColor = Color.White; 
    } 
} 

private void titlebar_MouseMove(object sender, MouseEventArgs e) 
{ 
    if (this.IsMouseDown == true) 
    { 
     //Move the form 
     this.Location = new Point(this.Left - (this.LastCursorPosition.X - e.X), this.Top - (this.LastCursorPosition.Y - e.Y)); 

     // Update works better than Invalidate();. 
     Update(); 
    } 
} 

private void titlebar_MouseUp(object sender, MouseEventArgs e) 
{ 
    this.IsMouseDown = false; 
    this.BackColor = fc; 
    tbox.BackColor = fc; 
} 

ответ

12

Invalidate отмечает окно, как необходимости обновляться (в какой-то момент). Обновление делает его там и тогда, если я правильно помню

Вот link объяснить разницу лучше, чем я смог бы

+2

Спасибо, связка Мартин. :) – 2010-02-18 06:25:53

31

Invalidate() просто добавляет в регионе к области обновления элемента управления. В следующий раз, когда получен WM_PAINT, область, которую вы признали недействительной плюс любые другие недействительные регионы, отмечены для рисования. Когда вызывается RedrawWindow(), он обычно отправляет сообщение WM_PAINT в очередь приложений. Система имеет право делать то, что она хочет, с тем, что обычно более оперативно, и красить, когда это возможно.

Если вы звоните Update(), вы получаете GDI + s UpdateWindow(), не отметит область для перерисовки, но толкает WM_PAINT непосредственно WNDPROC(), минуя очередь приложения.

Если нужно немедленное обновление элемента управления, используйте Refresh(), которые отменяют область затем сразу же вызывает Update().

+0

Я понимаю, что это старый пост, и, возможно, это должно быть опубликовано как отдельный вопрос, но я не понимаю, когда вы будете использовать Update и когда будете использовать Refresh. Кажется, что обе силы немедленно перекрашиваются. Можете ли вы уточнить? Благодаря! –

+4

@AdamPlocher Из комментария метода видно, что 'Invalidate()' просто флага области требует рисования, но не обязательно краска. 'Update()' заставляет все текущие недопустимые регионы перерисовывать, но ничего не флаг. И 'Refresh()' обертывает две операции вместе, сначала помещая область управления как недействительную, а затем сразу же запрашивая регион для обновления (перекраски). ** Редактировать: ** http://stackoverflow.com/a/952964/1718702 – HodlDwon