Мерцание во время обновления элементов управления в WinForms (например, DataGridView) - PullRequest
7 голосов
/ 15 сентября 2008

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

Это возможно с TreeViews:

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

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

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

Ответы [ 8 ]

8 голосов
/ 15 сентября 2008

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

this.SuspendLayout();

// Do something interesting.

this.ResumeLayout();
8 голосов
/ 05 июня 2012

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

Object.Visible = false;

//do update work

Object.Visible = true;

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

8 голосов
/ 15 сентября 2008

Двойная буферизация здесь не поможет, так как это только двойные буферы операций рисования, мерцание, которое видит OP, является результатом нескольких операций рисования:

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

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

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

Параметры 1 и 2 все еще будут немного мигать.

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

7 голосов
/ 16 сентября 2008

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

2 голосов
/ 17 октября 2008

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

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

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

SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true); 
SetStyle(ControlStyles.DoubleBuffer, true); 
1 голос
/ 15 сентября 2008

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

1 голос
/ 15 сентября 2008

Звучит так, будто вы хотите двойную буферизацию:

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

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

0 голосов
/ 10 августа 2017

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

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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...