powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / ListView. Мерцание.
21 сообщений из 21, страница 1 из 1
ListView. Мерцание.
    #34333948
?
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
?
Гость
Добрый день.

Подскажите, пожалуйста, как заставить не моргать стандартный ListView?
Есть формачка.
На ней ListView.
Код: plaintext
1.
      this.listView1.GridLines = true;
      this.listView1.View = System.Windows.Forms.View.Details;
Наполняю ListView (например, 1000 строк, 5 колонок):


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
      listView1.BeginUpdate();
      try
      {
        listView1.Items.Clear();
        for (int i = 0; i < 1000; i++)
        {
          ListViewItem li = listView1.Items.Add("Test" + i.ToString());
          li.SubItems.Add("SubItem" + i.ToString() + ".01");
          li.SubItems.Add("SubItem" + i.ToString() + ".02");
          li.SubItems.Add("SubItem" + i.ToString() + ".03");
          li.SubItems.Add("SubItem" + i.ToString() + ".04");
        }
      }
      finally
      {
        listView1.EndUpdate();
      }

1) После наполнения, когда он пытается отрисовать содержимое ListView, то происходит одно мерцание.

2) Потом изменяю размер колонок (не программно - тупо навожу мышкой на границу одной из колонок, опускаю клавишу, двигаю)... Жутко моргают все колонки справа от изменяющейся в размерах.

3) Растягиваю окно (тоже не программно - а мышью, ListView.Anchors = Top|Bottom|Left|Right), явно мерцают появляющиеся регионы ListView.

Четкое ощущение, что сначала рисуется Background, а затем рисуется содержимое.

У формы DoubleBuffered = true.

Как избавиться от мерцания???
...
Рейтинг: 0 / 0
ListView. Мерцание.
    #34333975
gentleman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
// Members are added one at a time, so call BeginUpdate to ensure 
    // the list is painted only once, rather than as each list item is added.
    ListView1.BeginUpdate();

    for(count = 0; count < foodList.Length; count++)
    {
        ListViewItem listItem = new ListViewItem(foodList[count]);
        listItem.SubItems.Add(foodPrice[count]);
        ListView1.Items.Add(listItem);
    }

    //Call EndUpdate when you finish adding items to the ListView.
    ListView1.EndUpdate();
    this.Controls.Add(this.ListView1);

Подробности в МСДН - BeginUpdate, EndUpdate
...
Рейтинг: 0 / 0
ListView. Мерцание.
    #34334013
?
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
?
Гость
1) Простите, зачем мне добавлять ListView на окно в RunTime?
Мне надо удалять с формы ListView каждый раз перед тем, как я буду обновлять в нем данные, а затем добавлять его на форму? При этом лочить как-нить окно?

2) А что делать с такими вещами, когда пользователь захочет изменить размер колонки или окна?
...
Рейтинг: 0 / 0
ListView. Мерцание.
    #34334286
chpasha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Может заюзать DataGridView?
...
Рейтинг: 0 / 0
ListView. Мерцание.
    #34334367
Фотография BusyMan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chpashaМожет заюзать DataGridView? они все напорядки медленнее... там эти 1000 строк несколько секунд может ждать... смотря как делать конечно ))
...
Рейтинг: 0 / 0
ListView. Мерцание.
    #34334530
chpasha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BusyMan chpashaМожет заюзать DataGridView? они все напорядки медленнее... там эти 1000 строк несколько секунд может ждать... смотря как делать конечно ))
Чеее :-) ???? В гриде медленней чем в листвью руками каждый итем и сабитем создавать и внутрь пихать??? :-) , это только если ты в каждом столбике грида AutoSizeMode на ширину содержимого поставишь. Если поставить фиксированную ширину или Fill - приятно удивишься разнице в скорости
...
Рейтинг: 0 / 0
ListView. Мерцание.
    #34334882
gentleman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, предыдущий мой пост был не в тему. Не вник в суть так сказать.
Единственное, что могу предложить, использовать блокировку окна.

Сначала импортим длл

Код: plaintext
1.
2.
 [DllImport("User32.DLL")]
        public static extern bool LockWindowUpdate(IntPtr hWnd);

потом обрабатываем события


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
 private void listView1_ColumnWidthChanged(object sender, ColumnWidthChangedEventArgs e)
        {
             LockWindowUpdate(IntPtr.Zero);
        }

        private void listView1_ColumnWidthChanging(object sender, ColumnWidthChangingEventArgs e)
        {           
             LockWindowUpdate(this.listView1.Handle);          
          
        }

Недостаток сего в том, что пока вы двигаете мышу, ширина столбца не меняется.
Вообще же у хедера столбца нет событий, и это я считаю неправильно. Можно было их юзать.

Может у кого-то будут другие идеи.
...
Рейтинг: 0 / 0
ListView. Мерцание.
    #34334934
Фотография BusyMan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chpasha Чеее :-) ???? В гриде медленней чем в листвью руками каждый итем и сабитем создавать и внутрь пихать??? :-) , это только если ты в каждом столбике грида AutoSizeMode на ширину содержимого поставишь. Если поставить фиксированную ширину или Fill - приятно удивишься разнице в скорости Я имею в виду, если также как там вручную по порядку создавать каждую строчку, а не заливать готовым DataSource
...
Рейтинг: 0 / 0
ListView. Мерцание.
    #34335391
?
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
?
Гость
Утро доброе.

Попробовал DataGridView....
Шут с ним с наполнением, медленно, не медленно... здесь мне надо еще разбираться.

Меня вот что волнует (может конечно я уже отстал от жизни и моих P3 ~2GHz 1GB недостаточно для обеспечения работоспособности приложений под .Net?), когда я изменяю размер колонки (и DataGridView при 100 строках, и ListView при тех же 100 строках) после того как наполнил, ну явное мерцание! Явно сначала закраска фона, а затем буковки с линиями рисуются...

Или может у меня неправильный .Net? (версия VS - 8.0.50727.42, Framework .Net v 2.0.50727)

По поводу LockWindowUpdate - ща попробую, но смущает то, что вроде как .Net, вроде как GDI+, вроде как все должно быть "весело и вкусно", а получается (прям и хочется запеть: "грустно и невкустно - Макдонаааалдс"), что без WinAPI обойтись так и не можем?

Ну, явно что-то я упускаю из виду... должно же быть какое-то решение в рамках .Net!
Кто его знает?
...
Рейтинг: 0 / 0
ListView. Мерцание.
    #34335469
dr-Wicked
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Может быть я чего то не дочитал, но пять тысяч сабитемов требуют виртуального режима imho.
Regards
dr-Wicked
...
Рейтинг: 0 / 0
ListView. Мерцание.
    #34335483
Фотография tAZAR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
?Добрый день.

Подскажите, пожалуйста, как заставить не моргать стандартный ListView?
....
Как избавиться от мерцания???

Если FW 2.0 (>) используйте "виртуальный" ListView (VirtualMode = true). Дальше - в сторону RetrieveVirtualItem.
И вообще - добавлять в цикле в листь вьюв элементы - это ужос! Есть ведь ListView.Items.AddRange - гораздо быстрее работает :-)
...
Рейтинг: 0 / 0
ListView. Мерцание.
    #34335720
?
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
?
Гость
Снова я.

Код: plaintext
to dr-Wicked

Хорошо пусть, будет не 5000 subitem, а 50! Т.е. я сделал 10 строк на 5 колонок....
Все равно МИГАЕТ при изменении размера колонок (не программно, а когда я себя ставлю на место пользователя). Мигает даже пустой ListView с включенной сеткой...
Мигает DataGridView на 10 записях (разовае мерцание при отпускании мыши после изменения размера колонки).

Господа, забудте про заполнение... Не важно как я наполнил этот ListView или DataGridView.
Меня беспокоит проблема отрисовки этих (стандартных для .Net?) элементов управления!
Отрисовка происходит визуально так:
1) Формируется фон (в какую-то область памяти, graphics, куда-то там еще или сразу на экран - не важно) и выводится на экран.
2) Формируется изображение и выводится на экран.
Проблема в наличии шага 1!!!

Код: plaintext
to gentleman

Спасибо за тему с LockWindowUpdate.
Действительно ЧАСТИЧНО помогает.

Но! Все равно на моей машине заметно (хоть и разовое), НО мерцание (получается такой же эффект как с DataGridView). Это всего навсего мы заменяем множественное мерцание на разовое !

Попытаюсь сам себе объяснить этот факт. (и может кому еще будет интересно). Если ошибаюсь - поправте.

Когда Windows нужно указать элементу управления, чтобы он перерисовался (полностью или частично), то (показывает Spy++):
а) Посылается сообщение WM_ERASEBKGND.
б) Посылается сообщение WM_PAINT.

Из-за (а) и возникает пункт 1 .

Как например это решается в Delphi (см. реализацию TWinControl.WMEraseBkgnd и TWinControl.WMPaint).
Если включена у Control'а DoubleBuffered, то
1) При получении сообщения WM_ERASEBKGND, если включен DoubleBuffered = True, то ничего .
2) При получении сообщения о WM_PAINT
- а) Формируем кусок памяти под рисование (вызов CreateCompatibleBitmap)
- б) Вызываем стандартный обработчик WM_ERASEBKGND (который будет стирать уже в этом куске памяти.
- в) Вызываем стандартный обработчик WM_PAINT, указывая ему, чтобы он тоже рисовал в этот кусочек памяти!
- г) Вывод полученого на экран!!!
Результат - нет мерцания!

Если вы делаете свой элемент управления (на базе стандартных с включением BS_OWNERDRAW), то обрабатываете:
1) На сообщение о стирании (WM_ERASEBKGND) фона ничего не делаем.
2) На сообщение о рисовании (WM_DRAWITEM) рисуем элемент.
Принцип тот почти же....

У .Net элементов я НЕ МОГУ найти DoubleBuffered! Он есть только у форм!
Что мне делать?

X) Ждать .Net 3.0?
Y) Делать свои компоненты?
Z) Есть уже готовые библиотеки, которые решают эту проблему??? Если да, где? По чем? Есть халява?
...
Рейтинг: 0 / 0
ListView. Мерцание.
    #34335816
chpasha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня конечно комп побыстрей твоего, но я пробовал специально только что на P4-1.6 с 256!!! мозгов и geforce mx200 - Я ПОНЯТИЯ НЕ ИМЕЮ О КАКОМ МЕРЦАНИИ ты в таком отчаянии тут говоришь. Если внимательно смотреть, специально, подчеркиваю - да, видно кое-какие подергивания. Но никакой реальной проблемы для не подготовленного глаза я не вижу, ты случайно дрова для видухи не забыл поставить? Мож у тебя древняя набортная? Попробуй на другом компе. Да компоненты нета в скорости перерисовки уступают нативным, но не на столько как ты говоришь, что прям давай функциями апи окно глушить.
...
Рейтинг: 0 / 0
ListView. Мерцание.
    #34335917
?
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
?
Гость
chpasha... да, видно кое-какие подергивания. Но никакой реальной проблемы для не подготовленного глаза я не вижу...

А я вижу в этом проблему...
И не P4 у сорудников в моей компании...
И никто не будет обновлять парк компов (~2 тыс) из-за того, что какой-то программишка (т.е. я) решил улучшить свое резюме пунктом владения .Net + C# и начал писать новые программы/утилиты на .Net + C# (речи о переписывании работающих приложений по .Net естественно пока не идет). А ведь хочется... понимаете (предложений по работе больше становится с C#... хочется быть уверенным, что на рынке есть предложения с той же з.п. что я имею... со своей Delphi я вижу только на меньшую... ну да ладно)?

Да, шкурный интерес, все новые прилаженица хочется писать на .Net...
Но если уж я их начну писать, то и выглядеть они должны не хуже, чем существующие (Delphi + VCL + DevExpress), иначе не поймут.

Ведь должно же быть решение! Должно же быть! Иначе почему C# оплачивается дороже Delphi?
Ну, да ладно - а то мы углубимся в пустую полемику (как товарищи из поста "На кой мне этот C#")...

Возвращаемся к нашим баранам.
Я просматривал тут посты на тему "DoubleBuffered" и "мерцание".
Проблема у всех как раз в эффекте предварительной заливки фона...

Я так понимаю она отключается только у форм (DoubleBuffered = true)...
Следовательно, я делаю вывод - пользоваться стандартными элементами не стоит.
И следовательно, надо искать библиотеки стороних производителей (которые рисование делали сами полностью).

Кто какие посоветует?
Есть, например, DevExpress под .Net 2.0?
А еще лучше - есть библиотеки с открытым кодом (чтоб самому поглядеть на чужой опыт)?
...
Рейтинг: 0 / 0
ListView. Мерцание.
    #34335938
chpasha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
четвертый пень я привел к тому, что если ты явно видишь мерцание на своем 2Гц (хотя имхо за мерцание видуха часто в ответе а не процик) то что-то у тебя не так. 1.6 это самое меньшее на чем я мог попробовать, увы. На счет того стоит ли переходить - тебе решать, особенно если ты ветку "на кой мне нужен" читаешь. Имхо медлительность интерфейса единственный пока в моих глазах серьезный недостаток (но опять таки не на столько все страшно).
...
Рейтинг: 0 / 0
ListView. Мерцание.
    #34335985
?
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
?
Гость
Почему видюха?
не она...

Мерцание тем больше заметно, чем больше пауза между заливкой фона и выводом самого изображения. А за формирование самого изобржаения отвечают инструкции приложения (там линию, здесь текст, здесь точечку... сам проц). Чем больше таких инструкций тем больше мерцание... чем сложнее у меня будет отрисовка, например, в ячейках того же грида, тем больше будет заметно мерцание.

Да не такой уж он (интерфейс) и медлительный... Нормальный... (пока на первый взгляд).
Проблема именно в этой предварительной заливке фона с выводом на экран!

Перефразирую вопрос.

A) Видел ли кто библиотеки, которые устранили проблему вывода фона на экран перед формированием изображения? Видел ли кто с открытым кодом?

B) Если писать самому контролы, то можно ли как-то перехватывать событие о прорисовке фона? Если да - натолкните на примерчики...
...
Рейтинг: 0 / 0
ListView. Мерцание.
    #34336071
dr-Wicked
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Так как лично я работаю жалким программиздишкой, за немеряно крутым компом купленным мною 3,5 года назад сделал так(ну чтобы не говорили про то что а вот на 1Г):
Код: plaintext
1.
2.
3.
4.
5.
6.
            int itms = 10000;
            ListViewItem[] lis =new ListViewItem[itms];
            for(int i=0;i<itms;i++){
                lis[i]=new ListViewItem(new string[5]{new string(Convert.ToChar(i),i),new string(Convert.ToChar(i),i),new string(Convert.ToChar(i),i),new string(Convert.ToChar(i),i),new string(Convert.ToChar(i),i)});
            }
            this.listView1.Items.AddRange(lis);
Заметен небольшой флик. Т.е. он не зависит от количества итемов.
Если внимательно смотрели за поведением флика, то ему подвержены смещаемые столбцы.
Могу порекомендовать ручную отрисовку итемов, если руководство готово за это платить деньги, а более полезных дел нет.
При ручной отрисовке советую отратить внимание на быстрое отсечение при ресайзе.
...
Рейтинг: 0 / 0
ListView. Мерцание.
    #34336091
Zorrik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Иногда тож замечаю, но тока когда в дебуге черезх терминал на виртуальной машине.
А так погляди
this.SetStyle(ControlStyles.OptimizedDoubleBuffer|ControlStyles.AllPaintingInWmPaint)
...
Рейтинг: 0 / 0
ListView. Мерцание.
    #34336102
chpasha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
?
B) Если писать самому контролы, то можно ли как-то перехватывать событие о прорисовке фона? Если да - натолкните на примерчики...
пишешь примерно так

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
class MyListViewEx : ListView 
{
    public MyListViewEx()
   {
      this.SetStyle(ControlStyles.DoubleBuffer | ControlStyles.OptimizedDoubleBuffer, true);
      this.SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw, true);
   }

   protected override OnPaintBackgorund ....
   {
      ...
   }
   
   protected override OnPaint...
   {
     ...
   }
}

И карты в руки
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
ListView. Мерцание.
    #39937218
AlexV1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Стандартный ListView взмаргивает не только когда эл-ты в него добавляешь, но и когда ресайзишь ширины колонок мышкой и даже когда водишь мышью над ним (редко но бывает).

Фантастика, но я нашел как полностью устранить мерцание .

Способ 1:


В конструкторе формы, на которой лежит стандартный listView1
выполнить:

Код: c#
1.
typeof(ListView).InvokeMember("DoubleBuffered", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetProperty, null, listView1, new object[] { true });


Способ 2:
Код: c#
1.
2.
3.
4.
5.
6.
7.
public class MyListView : ListView
{
    public MyListView()
    {
        this.DoubleBuffered = true; // это св-во доступно только в классах наследниках
    }
}
...
Рейтинг: 0 / 0
ListView. Мерцание.
    #39937696
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlexV1
Фантастика

С таким подходом MyКлассов не напасешься.
Лет 10+ делаю вот так, начиная с VB6:
Код: vbnet
1.
2.
3.
4.
    Dim lStyle As Integer
    lStyle = SendMessage(ListView1.Handle, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0)
    lStyle = lStyle Or LVS_EX_DOUBLEBUFFER
    Call SendMessage(ListView1.Handle, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, lStyle)
...
Рейтинг: 0 / 0
21 сообщений из 21, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / ListView. Мерцание.
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]