2012-03-23 139 views
2

我在詳細信息視圖中使用ListView控件,VirtualMode設置爲true,我發現無論何時添加新項目,都會將水平滾動條設置爲最左邊的位置。如果ListView不處於虛擬模式,則不會發生這種情況。 更新:如果您未啓用視覺樣式,這也不會發生。添加新項目時防止ListView自動水平滾動

您可以通過在細節模式創建一個簡單的ListView 2列添加類似下面看到這一點:

Timer timer = new Timer(); 

public Form1() 
{ 
    this.InitializeComponent(); 

    this.listView1.VirtualMode = true; 
    this.listView1.RetrieveVirtualItem += new RetrieveVirtualItemEventHandler(listView1_RetrieveVirtualItem); 
    this.listView1.VirtualListSize = 10; 

    timer.Interval = 250; 
    timer.Tick += new EventHandler(t_Tick); 
    timer.Start(); 
} 

void listView1_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e) 
{ 
    e.Item = new ListViewItem(new string[] {"Test", ""}); 
} 

void t_Tick(object sender, EventArgs e) 
{ 
    this.listView1.VirtualListSize += 1; 
} 

滾動列表視圖右側看到這個效果。

我該如何阻止這種情況發生?我有一個應用程序,其中的項目不斷添加到列表視圖,所以這種行爲是非常分散注意力。

回答

5

這似乎是一個已知的錯誤:ListView in virtual mode scrolls incorrectly

從微軟連接報告的最後註釋是:

這是與底層的Win32控制的問題。我們無法解決這個問題,操作系統團隊需要解決這個問題。

當然這是在2005年,所以它可能在Win 8中被固定?


與此同時,解決辦法似乎是:

創建繼承ListView和編寫以下代碼的新類:

private static FieldInfo _internalVirtualListSizeField; 

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

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

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

public void SetVirtualListSize(int size) 
{ 
    if (size < 0) 
    { 
     throw new ArgumentException("ListViewVirtualListSizeInvalidArgument"); 
    } 

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

現在更新代碼才能使用SetVirtualListSize方法,而不是原始的VirtualListSize屬性。

0x102f = LVM_SETITEMCOUNT 
2 = LVSICF_NOSCROLL 

參考: http://msdn.microsoft.com/en-us/library/bb761188%28VS.85%29.aspx

+0

在bug報告中似乎有horozontal VS垂直滾動之間有些混亂,但所列出的變通辦法解決我的問題(這表明,我認爲這個問題是不是** **在Win32控件中,但哦!) – Justin 2012-03-23 15:26:07

+1

我想我只是假設,如果它發生垂直滾動它也會影響水平滾動以及(顯然它確實)。值得在bug報告中增加一個註釋來說明這一點。 – 2012-03-23 15:28:17