Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / ListView. Мерцание. / 21 сообщений из 21, страница 1 из 1
15.02.2007, 15:55
    #34333948
?
?
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ListView. Мерцание.
Добрый день.

Подскажите, пожалуйста, как заставить не моргать стандартный 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
15.02.2007, 16:00
    #34333975
gentleman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ListView. Мерцание.
Код: 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
15.02.2007, 16:09
    #34334013
?
?
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ListView. Мерцание.
1) Простите, зачем мне добавлять ListView на окно в RunTime?
Мне надо удалять с формы ListView каждый раз перед тем, как я буду обновлять в нем данные, а затем добавлять его на форму? При этом лочить как-нить окно?

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

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

Код: 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
15.02.2007, 20:04
    #34334934
BusyMan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ListView. Мерцание.
chpasha Чеее :-) ???? В гриде медленней чем в листвью руками каждый итем и сабитем создавать и внутрь пихать??? :-) , это только если ты в каждом столбике грида AutoSizeMode на ширину содержимого поставишь. Если поставить фиксированную ширину или Fill - приятно удивишься разнице в скорости Я имею в виду, если также как там вручную по порядку создавать каждую строчку, а не заливать готовым DataSource
...
Рейтинг: 0 / 0
16.02.2007, 08:28
    #34335391
?
?
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ListView. Мерцание.
Утро доброе.

Попробовал 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
16.02.2007, 09:12
    #34335469
dr-Wicked
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ListView. Мерцание.
Может быть я чего то не дочитал, но пять тысяч сабитемов требуют виртуального режима imho.
Regards
dr-Wicked
...
Рейтинг: 0 / 0
16.02.2007, 09:22
    #34335483
tAZAR
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ListView. Мерцание.
?Добрый день.

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

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

Код: 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
16.02.2007, 11:10
    #34335816
chpasha
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ListView. Мерцание.
У меня конечно комп побыстрей твоего, но я пробовал специально только что на P4-1.6 с 256!!! мозгов и geforce mx200 - Я ПОНЯТИЯ НЕ ИМЕЮ О КАКОМ МЕРЦАНИИ ты в таком отчаянии тут говоришь. Если внимательно смотреть, специально, подчеркиваю - да, видно кое-какие подергивания. Но никакой реальной проблемы для не подготовленного глаза я не вижу, ты случайно дрова для видухи не забыл поставить? Мож у тебя древняя набортная? Попробуй на другом компе. Да компоненты нета в скорости перерисовки уступают нативным, но не на столько как ты говоришь, что прям давай функциями апи окно глушить.
...
Рейтинг: 0 / 0
16.02.2007, 11:35
    #34335917
?
?
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ListView. Мерцание.
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
16.02.2007, 11:41
    #34335938
chpasha
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ListView. Мерцание.
четвертый пень я привел к тому, что если ты явно видишь мерцание на своем 2Гц (хотя имхо за мерцание видуха часто в ответе а не процик) то что-то у тебя не так. 1.6 это самое меньшее на чем я мог попробовать, увы. На счет того стоит ли переходить - тебе решать, особенно если ты ветку "на кой мне нужен" читаешь. Имхо медлительность интерфейса единственный пока в моих глазах серьезный недостаток (но опять таки не на столько все страшно).
...
Рейтинг: 0 / 0
16.02.2007, 11:55
    #34335985
?
?
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ListView. Мерцание.
Почему видюха?
не она...

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

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

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

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

B) Если писать самому контролы, то можно ли как-то перехватывать событие о прорисовке фона? Если да - натолкните на примерчики...
...
Рейтинг: 0 / 0
16.02.2007, 12:16
    #34336071
dr-Wicked
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ListView. Мерцание.
Так как лично я работаю жалким программиздишкой, за немеряно крутым компом купленным мною 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
16.02.2007, 12:21
    #34336091
Zorrik
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ListView. Мерцание.
Иногда тож замечаю, но тока когда в дебуге черезх терминал на виртуальной машине.
А так погляди
this.SetStyle(ControlStyles.OptimizedDoubleBuffer|ControlStyles.AllPaintingInWmPaint)
...
Рейтинг: 0 / 0
16.02.2007, 12:23
    #34336102
chpasha
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ListView. Мерцание.
?
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
Период между сообщениями больше года.
13.03.2020, 17:07
    #39937218
AlexV1
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ListView. Мерцание.
Стандартный 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
16.03.2020, 05:13
    #39937696
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ListView. Мерцание.
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
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / ListView. Мерцание. / 21 сообщений из 21, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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