2012-03-23 97 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