получен из ListView, неправильно рисует - PullRequest
0 голосов
/ 29 октября 2010

У меня был обычный Forms.ListView и я преобразовал его в виртуальный список.Реализовал RetrieveVirtualItem и все работало нормально.

Тогда я решил, что добавлю кеш, и в итоге мне понадобится сортировка, и кто знает, что еще.Так как я унаследовал код, и он уже был несколько беспорядочным, я решил скопировать свои изменения и перенести их в отдельный класс, а именно: наследовать от ListView, например, class MyOwnListView : ListView

, поэтому я переместил егоа также добавил CacheVirtualItems.

После реализации обоих этих методов я заменил:

private System.Windows.Forms.ListView someListView; 

на

private MyOwnListView someListView; 

в главной форме.

Пока все хорошо ... он работает, но не вылетает (а у меня сейчас только около 60 элементов ...), когда я перемещаю полосу прокрутки, многие из них не перекрашиваются, поэтому выувидеть пустые белые строки, и иногда он будет перекрашивать / показывать после нажатия на эту строку.Я также получаю частично отображаемую и нарисованную строку, например, верхняя часть строки не будет отображаться полностью.

Я не уверен, в чем проблема, я попытался добавить DoubleBuffered=true; Я также добавилмоему конструктору следующее: (по какому-то предложению я нашел где-то здесь и / или гуглил ..)

SetStyle( ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true );
SetStyle( ControlStyles.EnableNotifyMessage, true );

и этот метод:

 protected override void OnNotifyMessage( Message m )
    {
        //Filter out the WM_ERASEBKGND message
        if ( m.Msg != 0x14 )
        {
            base.OnNotifyMessage( m );
        }
    }

Мой код в целом оченьпримерно так: .. просто чтобы дать вам представление:

public class MyListView: ListView
{
   private ListViewItem[] cache;
   private int firstItem;

public MyListView()
{
SetStyle( ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true );
SetStyle( ControlStyles.EnableNotifyMessage, true );

 RetrieveVirtualItem += new RetrieveVirtualItemEventHandler( xxx_RetrieveVirtualItem );
 CacheVirtualItems += new CacheVirtualItemsEventHandler( xxx_CacheVirtualItems );
}
 private void  xxx_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
 {
  if (cache != null && e.ItemIndex >= firstItem && e.ItemIndex < firstItem + cache.Length)
                e.Item = cache[e.ItemIndex - firstItem];
            else
               e.Item = GetItem(e.ItemIndex);
  }

 private void xxx_CacheVirtualItems(object sender, CacheVirtualItemsEventArgs e)
 {
 if (cache != null && e.StartIndex >= firstItem && e.EndIndex <= firstItem + cache.Length)
                return;

  firstItem  = e.StartIndex;
  int length = e.EndIndex - e.StartIndex + 1;
   cache = new ListViewItem[length];

   for (int i = 0; i < cache.Length; i++) 
         cache[i] = GetItem(firstItem + i);
  }

Now, GetItem, basically accesses a List<someobject>, gets the object out of list, and based on that
it creates new ListViewItem and returns it.

}

РЕДАКТИРОВАТЬ: я добавил некоторый код отладки в xxx_CacheVirtualItems.И кажется, что каждый раз, когда я прокручиваю, он возвращается, что элемент не был найден, и снова добавляет его в кэш.Пока не знаю, почему.Я ожидаю, что после первой прокрутки все будет в кеше.Я все еще ищу.

Я также попытался добавить:

Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);


and tried //Application.SetCompatibleTextRenderingDefault(true);

Это приложение не имело их вообще ... эти две строки сделали что-то интересное.SetCompatibleTextRenderingDefault со значением false вообще не прокручивался, в то время как SetCompatibleTextRenderingDefault со значением true прокручивал, но только вниз и, когда я достиг дна, остановился.но на экране не было проблем с рисованием / обновлением ..

1 Ответ

0 голосов
/ 30 октября 2010

ОК, ребята, я понял это.Это очень странно, но я непреднамеренно изменил какой-то код и не думал, что это было большое дело, позвольте мне перефразировать его, поэтому в моем GetItem(index); коде

То, что у меня было:*

...... ...

ну, я хотел быть "элегантным", я изменил это на:

ListViewItem v = new ListViewItem(....,0);
v.SubItems.AddRange( new string[] { prop1, prop2, prop3, , , ,....});

И это было проблемой,Я просто изменил его обратно и волшебным образом он начал работать.

...