2009-10-20 76 views
4

我知道這聽起來很複雜重現,但請跟我來:在VirtualMode C#的ListView閃爍

您有VirtualMode = true.

一個ListView選擇一個項目,向下滾動,這樣的選擇的項目在視覺區域之外,然後嘗試向ListView添加另一個項目。

你會看到一瞬間它表現異常,看到一些閃爍。 如果您將情況升級並嘗試快速添加大量項目(我每秒添加大約20次),您會發現小問題變得非常大。這是閃爍和無效項目的組合。

我調查了這個問題,似乎ListView爲所選項目生成了很多RetrieveVirtualItem事件(即使它顯然不可見)。

這似乎是當我添加一個新項目(增加VirtualListSize)ListView首先嚐試專注於選定的項目,然後返回到以前的位置。

有沒有人遇到同樣的問題?

回答

1

各種控件都有一個受保護的DoubleBuffered屬性。您可以嘗試從ListView派生自己的DBListView,並在其構造函數中將其DoubleBuffered屬性設置爲true。

+0

既然我已經發布了這個問題已經有一段時間了,我會嘗試找到該項目並嘗試解決您的問題。謝謝 – 2010-09-05 17:29:10

5

這裏有一個解決此問題的派生類。

使用SetVirtualListSize()方法代替常規VirtualListSize

public class FlickerFreeListView : ListView 
{ 
    #region Static Functionality 

    private static FieldInfo _internalVirtualListSizeField; 

    static FlickerFreeListView() 
    { 
     _internalVirtualListSizeField = typeof(ListView).GetField("virtualListSize", System.Reflection.BindingFlags.NonPublic | BindingFlags.Instance); 

     if (_internalVirtualListSizeField == null) 
     { 
      string msg = "Private field virtualListSize in type System.Windows.Forms.ListView is not found. Workaround is incompatible with installed .NET Framework version, running without workaround."; 
      Trace.WriteLine(msg); 
     } 
    } 

    #endregion 


    [DllImport("user32.dll", CharSet = CharSet.Auto)] 
    private static extern IntPtr SendMessage(HandleRef hWnd, int msg, IntPtr wParam, IntPtr lParam); 

    internal IntPtr SendMessage(int msg, IntPtr wparam, IntPtr lparam) 
    { 
     return SendMessage(new HandleRef(this, this.Handle), msg, wparam, lparam); 
    } 

    public void SetVirtualListSize(int size) 
    { 
     // if workaround incompatible with current framework version (usually MONO) 
     if (_internalVirtualListSizeField == null) 
     { 
      VirtualListSize = size; 
     } 
     else 
     { 
      if (size < 0) 
      { 
       throw new ArgumentException("ListViewVirtualListSizeInvalidArgument"); 
      } 

      _internalVirtualListSizeField.SetValue(this, size); 
      if ((base.IsHandleCreated && this.VirtualMode) && !base.DesignMode) 
      { 
       SendMessage(0x102f, new IntPtr(size), new IntPtr(2)); 
      } 
     } 
    } 
} 
+0

謝謝你,但是我解決問題已經很長時間了。我無法再測試這個解決方案。我看到它有一些upvotes所以如果有人測試這個,它的工作,然後在這裏寫一個評論,所以我可以接受這個答案。 – 2013-04-29 19:49:06