2008-09-15 2 views
7

В моем приложении у меня есть элемент управления DataGridView, который отображает данные для выбранного объекта. Когда я выбираю другой объект (в выпадающем списке выше), мне нужно обновить сетку. К сожалению, разные объекты имеют совершенно разные данные, даже разные столбцы, поэтому мне нужно очистить все существующие данные и столбцы, создать новые столбцы и добавить все строки. Когда это будет сделано, весь контроль мерцает ужасно, и это требует возраста. Есть ли общий способ получить элемент управления в состоянии обновления, чтобы он не перерисовывался, а затем перерисовывал его после завершения всех обновлений?Мерцание во время обновлений элементам управления в WinForms (например, DataGridView)

Это, конечно, возможно с TreeViews:

myTreeView.BeginUpdate(); 
try 
{ 
    //do the updates 
} 
finally 
{ 
    myTreeView.EndUpdate(); 
} 

Есть ли общий способ сделать это с другими органами управления, DataGridView в частности?

ОБНОВЛЕНИЕ: Извините, я не уверен, что я был достаточно ясен. Я вижу «мерцающий», потому что после одного редактирования управления получает перекрасили на экране, так что вы можете увидеть полосу прокрутки усадка и т.д.

+0

добавить это в свой DataGridView DoubleBuffered (true); –

ответ

7

Вместо добавления строк сетки одного данных в то время, используйте метод DataGridView.Rows.AddRange добавить все строки сразу , Это должно обновлять только один раз. Существует также DataGridView.Columns.AddRange, чтобы сделать то же самое для столбцов.

+0

Привет, это кажется лучшим, что вы можете получить с DataGridView – Grzenio

1

Похоже, вы хотите двойной буферизации:

http://www.codeproject.com/KB/graphics/DoubleBuffering.aspx

Хотя это в основном используется для отдельных элементов управления, вы можете реализовать это в своем элементе управления или форме Windows Forms.

+2

Я пробовал двойную буферизацию, но это не помогло. Я думаю, проблема в том, что она пытается перерисовать после каждой добавляемой строки, поэтому она заканчивает обновление первых строк несколько раз. – Grzenio

1

К сожалению, я думаю, что thins может быть просто побочным продуктом .net framework. Я испытываю подобное мерцание, хотя и с пользовательскими элементами управления. Многие из справочных материалов, которые я прочитал, указывают на это, наряду с тем, что метод двойной буферизации не смог удалить мерцание для меня.

6

Двойная буферизация не поможет, так что только двойные буферы окрашивать операции, мерцающий ОП видит является результатом нескольких операций краски:

  • Очистить содержимое управления -> перекрашивать
  • Очистить столбцы -> перекрашивать
  • Заполняем новые столбцы -> перекрашивать
  • Добавить строки -> перекрашивать

так что четыре обновления для обновления управления, следовательно, мерцание. К сожалению, не все стандартные элементы управления имеют BeginUpdate/EndUpdate, которые будут удалять все вызовы перерисовки до тех пор, пока не будет вызван EndUpdate. Вот что вы можете сделать:

  1. Есть различные управления для каждого набора данных и показать/скрыть элементы управления,
  2. Удалить элемент управления из родительского, обновления, а затем добавить элемент управления снова,
  3. Написать свой собственный контроль.

Опции 1 и 2 по-прежнему будут мерцать.

В программе .Net GUI, над которой я работаю, я создал набор пользовательских элементов управления, которые устранили все мерцание.

+0

Да, я уверен, что это точно проблема. И поскольку мне нужно добавить> 50 строк, вы можете увидеть, как растет сетка. Когда вы создали свои элементы управления, вы расширили существующий вид сетки данных или написали новый с нуля? – Grzenio

+0

Я написал их с нуля, полученные из UserControl, и все они очень специфичны для приложений. – Skizz

8

Элемент управления .NET поддерживает методы SuspendLayout и ResumeLayout. Выберите соответствующий родительский элемент управления (т.элемент управления, который принимает элементы управления вы хотите заполнить) и сделать что-то вроде следующего:

this.SuspendLayout(); 

// Do something interesting. 

this.ResumeLayout(); 
+2

Да, я попробовал, но он просто не работает :( – Grzenio

2

Это сработало для меня.

http://www.syncfusion.com/faq/windowsforms/search/558.aspx

В основном это предполагает получения от требуемого контроля и установить следующие стили.

SetStyle(ControlStyles.UserPaint, true); 
SetStyle(ControlStyles.AllPaintingInWmPaint, true); 
SetStyle(ControlStyles.DoubleBuffer, true); 
7

Люди, кажется, забывают простую фикс для этого:

Object.Visible = false; 

//do update work 

Object.Visible = true; 

Я знаю, что это кажется странным, но это работает. Когда объект не отображается, он не будет перерисовываться. Тем не менее, вам необходимо обновить begin и end.

+0

У этого должно быть намного больше очков, это бы сэкономило бы много времени. работа для моего случая использования, но это было прекрасно. Спасибо! –

0

Вы также можете попробовать это, его работу.

public static void DoubleBuffered(Control formControl, bool setting) 
{ 
    Type conType = formControl.GetType(); 
    PropertyInfo pi = conType.GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic); 
    pi.SetValue(formControl, setting, null); 
} 
Смежные вопросы