Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Мерцание ListView C#  (Прочитано 23738 раз)
0 Пользователей и 1 Гость смотрят эту тему.
kisilevski
Постоялец

ru
Offline Offline
Пол: Мужской

WWW
« : 13-08-2009 04:11 » 

При частом изменении текста в subitemах контрола ListView, работающего в режиме report, наблюдается мерцание контрола, подобное тому, которое можно наблюдать, когда по телевизору показывают телевизор. То есть примерно два раза в минуту по ListView снизу вверх пробегает волна мерцания, причём она не зависит от частоты обновления текста.

Главное окно программы содержит панель с графиками и ListView, в котором отображаются значения по мере того, как юзер на мыше ездит по графику.

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

Существуют ли какие-нибудь практические подходы к решению данного вопроса?
(когда я лет 10 назад делал это на MFC, такой проблемы вообще не возникало..  А черт его знает...)


Мышь обрабатываю в добавленном к основному (не перегруженном) обработчике,
и в нём же вызываю функцию изменения текста в subitemах, которая делает это следующим образом:

Код:
            if(m_Graph.m_Lines!=null)
            {
                if (m_Graph.m_Lines[0].m_LVI != null)
                    m_Graph.m_Lines[0].m_LVI.SubItems[1].Text = m_Srz[si].Pgr_Str();

                if (m_Graph.m_Lines[1].m_LVI != null)
                    m_Graph.m_Lines[1].m_LVI.SubItems[1].Text = m_Srz[si].Ptm_Str();

                if (m_Graph.m_Lines[2].m_LVI != null)
                    m_Graph.m_Lines[2].m_LVI.SubItems[1].Text = m_Srz[si].Ptc_Str();

                if (m_Graph.m_Lines[3].m_LVI != null)
                    m_Graph.m_Lines[3].m_LVI.SubItems[1].Text = m_Srz[si].Pur_Str();

               // итд
            }



Записан

Ложки нет. See MSDN for details.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 13-08-2009 05:53 » 

1) по моему, там есть встроенное свойство doublebuffer - попробуй включить

2) если нету/ не помогло, то не выводи текст в на контрол сразу, а буферизируй, а вывод делай не чаще, скажем, чем раз в 1/3 секунды

(это только мысли, не пробовал Улыбаюсь )
Записан

Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 13-08-2009 05:55 » 

Включить на форме двойную буферизацию отображения. Если .NET 2.0 и выше, то у формы свойство DoubleBuffered. Если ниже, то там похитрее надо - стилями настраивать.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #3 : 13-08-2009 08:00 » 

Я так понимаю у тебя этих items много, а приведённый код соответствует одному событию мыши. Апдейт контрола происходит при каждом присваивании текста. Может попоробовать отключить вначале апдейт контрола, а после присваиваивания всех текстов сделать invalidate?
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
kisilevski
Постоялец

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #4 : 14-08-2009 03:58 » 

Спасибо, вечером попробую, в понедельник расскажу, что получилось.
.Net 3.5 (2008 студия)
itemов ожидается в пределе менее 30ти,то есть можно считать, что их совсем мало
В MFC так и делал - SetRedraw(FALSE) / SetRedraw(TRUE).
Записан

Ложки нет. See MSDN for details.
kisilevski
Постоялец

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #5 : 19-08-2009 08:02 » 

 Получилось!

1) doublebuffer на форме не помогло - ничего не изменилось.
2) Приостановить обновление - не нашёл как сделать. пытался перегрузить лист, но в OnPaint он вообще не заходит (брякпоинт ничего не дождался)

3) Завёл будильник, вывожу не чаще десяти раз в секунду, мерцания не стало, только полоски грида чуть вздрагивают, но это уже если сильно всматриваться.

Спасибо всем за ответы! Улыбаюсь
Записан

Ложки нет. See MSDN for details.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 19-08-2009 08:44 » 

Фигня какая-то насчёт и DoubleBuffer и OnPaint.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
x77
Команда клуба

ro
Offline Offline
Пол: Мужской
меняю стакан шмали на обратный билет с Марса.


« Ответ #7 : 31-08-2009 11:08 » 

не знаю, реализовано ли это в сишарпе, но у стандартного виндового листвью есть методы Items.BeginUpdate .. Items.EndUpdate, отключающие перерисовку при изменении списка.
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #8 : 31-08-2009 11:16 » new

x77, наверное хотел сказать "у стандартного дельфийского" Улыбаюсь
Записан

x77
Команда клуба

ro
Offline Offline
Пол: Мужской
меняю стакан шмали на обратный билет с Марса.


« Ответ #9 : 31-08-2009 11:24 » 

Алексей1153++, "стандартные дельфийские" компоненты представляют собой врапперы вокруг виндовых элементов управления и практически все юзают виндовое же апи.

сейчас посмотрел по исходникам, у "нас" отключение отрисовки эквивалентно SendMessage(Handle, WM_SETREDRAW, 0, 0);
Записан

kisilevski
Постоялец

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #10 : 02-10-2009 05:00 » 

Нашёл, как активировать встроенную функциональность doublebufferingа.
В конструкторе класса, унаследованного от ListView добавил:
Код:
SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);

Теперь мерцания не стало, даже когда убрал фильтрование для 10 обновлений в секунду.
Записан

Ложки нет. See MSDN for details.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #11 : 02-10-2009 05:42 » 

а процессор сильно грузится без фильтра ?
Записан

kisilevski
Постоялец

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #12 : 02-10-2009 05:56 » 

До предела грузится.
В самодельном контроле я делаю Invalidate только нужного мне места и рисование только того, что подлежит перерисовке всвязис, и, соответственно, процессор не сильно грузится от этого. Как попросить об этом же самом лист - пока не знаю, и не знаю, будет ли такая оптимизация эффективной.
Короче, пока не всецело прусь от C#.
Записан

Ложки нет. See MSDN for details.
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines