Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当所选项目不可见时,VirtualMode中的C ListView会闪烁_C#_Listview_Flicker_Virtualmode - Fatal编程技术网

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

C# 当所选项目不可见时,VirtualMode中的C ListView会闪烁,c#,listview,flicker,virtualmode,C#,Listview,Flicker,Virtualmode,我知道这听起来很复杂,但请跟我来: 您有一个VirtualMode=true的ListView 选择一个项目,向下滚动,使所选项目超出可视区域,然后尝试向ListView添加另一个项目 你会看到,在一瞬间,它的行为异常,并看到某种闪烁。 如果你将情况升级,并尝试快速添加大量项目,我每秒添加大约20次,你会看到小问题变得非常严重。这是闪烁和无效项目的组合 我已经调查了这个问题,ListView似乎为所选项目生成了很多RetrieveVirtualItem事件,尽管它显然不可见 似乎当我添加一个新项

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

您有一个VirtualMode=true的ListView

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

你会看到,在一瞬间,它的行为异常,并看到某种闪烁。 如果你将情况升级,并尝试快速添加大量项目,我每秒添加大约20次,你会看到小问题变得非常严重。这是闪烁和无效项目的组合

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

似乎当我添加一个新项目时,会增加VirtualListSize,ListView会首先尝试关注所选项目,然后返回到以前的位置


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

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

这里是一个解决此问题的派生类

使用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));
            }
        }
    }
}