首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当所选项目不可见时,VirtualMode中的C# ListView闪烁

当所选项目不可见时,VirtualMode中的C# ListView闪烁
EN

Stack Overflow用户
提问于 2009-10-21 01:02:16
回答 2查看 2.2K关注 0票数 4

我知道这听起来很复杂,但请跟我来:

您有一个带有VirtualMode = true.的ListView

选择一个项目,向下滚动,使所选项目超出可视区域,然后尝试将另一个项目添加到ListView。

您将看到在瞬间它的行为异常,并看到某种闪烁。如果你升级情况并尝试非常快地添加很多项目(我每秒添加大约20次),你会发现小问题变得非常大。它是闪烁和无效项的组合。

我已经调查过这个问题,似乎ListView会为所选的项目生成很多RetrieveVirtualItem事件(尽管它显然不可见)。

似乎当我添加一个新项目(增加VirtualListSize)时,ListView首先尝试将焦点放在所选项目上,然后返回到前一个位置。

有没有人遇到过同样的问题?

EN

回答 2

Stack Overflow用户

发布于 2010-09-30 19:57:39

下面是一个派生类,它解决了这个问题。

使用SetVirtualListSize()方法而不是常规的VirtualListSize

代码语言:javascript
复制
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));
            }
        }
    }
}
票数 5
EN

Stack Overflow用户

发布于 2010-08-06 19:55:00

各种控件都具有受保护的DoubleBuffered属性。您可以尝试从ListView派生自己的DBListView,并在其构造函数中将其DoubleBuffered属性设置为true。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1596005

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档