Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.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# ListView控件中闪烁(OwnerDraw,虚拟)_C#_Winforms_Listview_Flicker_Ownerdrawn - Fatal编程技术网

C# ListView控件中闪烁(OwnerDraw,虚拟)

C# ListView控件中闪烁(OwnerDraw,虚拟),c#,winforms,listview,flicker,ownerdrawn,C#,Winforms,Listview,Flicker,Ownerdrawn,这一问题可被视为对这一问题的后续行动 我在虚拟模式下有一个列表视图控件,我尝试执行自定义绘图。项目渲染通过以下方法完成: protected override void OnDrawItem(DrawListViewItemEventArgs eventArgs) 如参考问题中所述,自定义图形引入鼠标悬停事件时的闪烁。调试器告诉我,这是由于触发了过多的自定义绘制事件造成的 现在-参考问题的公认答案告诉我们: 这是.NET的ListView中的一个bug,您无法通过 双缓冲 那么,这些信息

这一问题可被视为对这一问题的后续行动

我在
虚拟模式下有一个
列表视图
控件
,我尝试执行自定义绘图。项目渲染通过以下方法完成:

protected override void OnDrawItem(DrawListViewItemEventArgs eventArgs) 
如参考问题中所述,自定义图形引入鼠标悬停事件时的闪烁。调试器告诉我,这是由于触发了过多的自定义绘制事件造成的


现在-参考问题的公认答案告诉我们:

这是.NET的ListView中的一个bug,您无法通过 双缓冲

  • 那么,这些信息有多可靠?这真的是一个bug吗?或者我们只是试图切断一部分信息,希望它不会改变可见的行为

  • 如果我在
    虚拟模式下为
    列表视图
    设置了我的所有者绘图例程,
    我可以抑制这些
    自定义绘图
    事件,并且只在
    WM_PAINT
    中执行绘图,这是真的吗?或者,在某些情况下可能不正确

  • System.Windows.Forms
    控件能够在
    WM\u PAINT
    中进行所有绘制而不改变其初始行为的先决条件是什么


至少对于OnDrawItem的双缓冲来说,存在错误是不正确的,但这有点愚蠢:可以设置一个受保护的属性,但需要覆盖ListView。我创建了这样的类:

public class MyListView : ListView
{
    public MyListView()
        : base()
    {
        DoubleBuffered = true;
    }
}
然后在MyForm.Designer.cs文件中,我用以下行更改ListView的实例化:

private ListView myListView;

this.myListView = new MyListView();
OnDrawItem将像一个符咒一样工作

比如,虽然不确定,但是

我认为
ListView.BeginUpdate()
ListView.EndUpdate()
将解决这个问题

也许是这样:

protected override void OnDrawItem(DrawListViewItemEventArgs eventArgs)
{
    ListView.BeginUpdate();
    //Do Works Here
    ListView.EndUpdate();
}
更新 另一种选择可能是使用
BackgroundWorker
中的新线程更新ListView。。。 我在应用程序中与
BeginUpdate()
/
EndUpDate()
一起实现了这一点,发现它比
BeginUpdate()
/
EndUpDate()
要快得多

更新 我找到了另一个正在工作的助手类,它是由
Brian Gillespie
提供的:

public enum ListViewExtendedStyles
{
    /// <summary>
    /// LVS_EX_GRIDLINES
    /// </summary>
    GridLines = 0x00000001,
    /// <summary>
    /// LVS_EX_SUBITEMIMAGES
    /// </summary>
    SubItemImages = 0x00000002,
    /// <summary>
    /// LVS_EX_CHECKBOXES
    /// </summary>
    CheckBoxes = 0x00000004,
    /// <summary>
    /// LVS_EX_TRACKSELECT
    /// </summary>
    TrackSelect = 0x00000008,
    /// <summary>
    /// LVS_EX_HEADERDRAGDROP
    /// </summary>
    HeaderDragDrop = 0x00000010,
    /// <summary>
    /// LVS_EX_FULLROWSELECT
    /// </summary>
    FullRowSelect = 0x00000020,
    /// <summary>
    /// LVS_EX_ONECLICKACTIVATE
    /// </summary>
    OneClickActivate = 0x00000040,
    /// <summary>
    /// LVS_EX_TWOCLICKACTIVATE
    /// </summary>
    TwoClickActivate = 0x00000080,
    /// <summary>
    /// LVS_EX_FLATSB
    /// </summary>
    FlatsB = 0x00000100,
    /// <summary>
    /// LVS_EX_REGIONAL
    /// </summary>
    Regional = 0x00000200,
    /// <summary>
    /// LVS_EX_INFOTIP
    /// </summary>
    InfoTip = 0x00000400,
    /// <summary>
    /// LVS_EX_UNDERLINEHOT
    /// </summary>
    UnderlineHot = 0x00000800,
    /// <summary>
    /// LVS_EX_UNDERLINECOLD
    /// </summary>
    UnderlineCold = 0x00001000,
    /// <summary>
    /// LVS_EX_MULTIWORKAREAS
    /// </summary>
    MultilWorkAreas = 0x00002000,
    /// <summary>
    /// LVS_EX_LABELTIP
    /// </summary>
    LabelTip = 0x00004000,
    /// <summary>
    /// LVS_EX_BORDERSELECT
    /// </summary>
    BorderSelect = 0x00008000,
    /// <summary>
    /// LVS_EX_DOUBLEBUFFER
    /// </summary>
    DoubleBuffer = 0x00010000,
    /// <summary>
    /// LVS_EX_HIDELABELS
    /// </summary>
    HideLabels = 0x00020000,
    /// <summary>
    /// LVS_EX_SINGLEROW
    /// </summary>
    SingleRow = 0x00040000,
    /// <summary>
    /// LVS_EX_SNAPTOGRID
    /// </summary>
    SnapToGrid = 0x00080000,
    /// <summary>
    /// LVS_EX_SIMPLESELECT
    /// </summary>
    SimpleSelect = 0x00100000
}

public enum ListViewMessages
{
    First = 0x1000,
    SetExtendedStyle = (First + 54),
    GetExtendedStyle = (First + 55),
}

/// <summary>
/// Contains helper methods to change extended styles on ListView, including enabling double buffering.
/// Based on Giovanni Montrone's article on <see cref="http://www.codeproject.com/KB/list/listviewxp.aspx"/>
/// </summary>
public class ListViewHelper
{
    private ListViewHelper()
    {
    }

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern int SendMessage(IntPtr handle, int messg, int wparam, int lparam);

    public static void SetExtendedStyle(Control control, ListViewExtendedStyles exStyle)
    {
        ListViewExtendedStyles styles;
        styles = (ListViewExtendedStyles)SendMessage(control.Handle, (int)ListViewMessages.GetExtendedStyle, 0, 0);
        styles |= exStyle;
        SendMessage(control.Handle, (int)ListViewMessages.SetExtendedStyle, 0, (int)styles);
    }

    public static void EnableDoubleBuffer(Control control)
    {
        ListViewExtendedStyles styles;
        // read current style
        styles = (ListViewExtendedStyles)SendMessage(control.Handle, (int)ListViewMessages.GetExtendedStyle, 0, 0);
        // enable double buffer and border select
        styles |= ListViewExtendedStyles.DoubleBuffer | ListViewExtendedStyles.BorderSelect;
        // write new style
        SendMessage(control.Handle, (int)ListViewMessages.SetExtendedStyle, 0, (int)styles);
    }
    public static void DisableDoubleBuffer(Control control)
    {
        ListViewExtendedStyles styles;
        // read current style
        styles = (ListViewExtendedStyles)SendMessage(control.Handle, (int)ListViewMessages.GetExtendedStyle, 0, 0);
        // disable double buffer and border select
        styles -= styles & ListViewExtendedStyles.DoubleBuffer;
        styles -= styles & ListViewExtendedStyles.BorderSelect;
        // write new style
        SendMessage(control.Handle, (int)ListViewMessages.SetExtendedStyle, 0, (int)styles);
    }
}
公共枚举ListViewExtendedStyles { /// ///LVS_EX_网格线 /// 网格线=0x00000001, /// ///LVS_EX_子项图像 /// 子项图像=0x00000002, /// ///LVS_EX_复选框 /// 复选框=0x00000004, /// ///LVS_EX_轨迹选择 /// TrackSelect=0x00000008, /// ///LVS_EX_HEADERDRAGDROP /// HeaderDragDrop=0x00000010, /// ///LVS_EX_FULLROWSELECT /// FullRowSelect=0x00000020, /// ///LVS_EX_One单击激活 /// OneClickActivate=0x00000040, /// ///LVS_EX_Two单击激活 /// 两次单击激活=0x00000080, /// ///LVS_EX_FLATSB /// FlatsB=0x00000100, /// ///LVS_前_地区 /// 区域=0x00000200, /// ///LVS_EX_信息提示 /// InfoTip=0x00000400, /// ///LVS_EX_UNDERLINEHOT /// 下划线HOT=0x00000800, /// ///LVS_EX_UNDERLINECOLD /// 下划线COLD=0x00001000, /// ///LVS_EX_多工作区 /// 多工作区=0x000020000, /// ///LVS_EX_LABELTIP /// LabelTip=0x00004000, /// ///LVS_EX_BORDERSELECT /// BorderSelect=0x00008000, /// ///LVS_EX_双缓冲区 /// DoubleBuffer=0x00010000, /// ///LVS_EX_HIDELABELS /// HideLabels=0x00020000, /// ///LVS_EX_SINGLEROW /// 单行=0x00040000, /// ///LVS_EX_SNAPTOGRID /// SnapToGrid=0x00080000, /// ///LVS_EX_SIMPLESELECT /// SimpleSelect=0x00100000 } 公共枚举ListViewMessages { 第一个=0x1000, SetExtendedStyle=(第一个+54), GetExtendedStyle=(第一个+55), } /// ///包含用于更改ListView上扩展样式的帮助器方法,包括启用双缓冲。 ///根据Giovanni Montrone关于 /// 公共类ListViewHelper { 私有ListViewHelper() { } [DllImport(“user32.dll”,CharSet=CharSet.Auto)] 私有静态外部int SendMessage(IntPtr句柄、int messg、int wparam、int lparam); 公共静态void SetExtendedStyle(控件控件,ListViewExtendedStyles exStyle) { ListViewExtendedStyles; styles=(ListViewExtendedStyles)SendMessage(control.Handle,(int)ListViewMessages.GetExtendedStyle,0,0); 样式|=exStyle; SendMessage(control.Handle,(int)ListViewMessages.SetExtendedStyle,0,(int)styles); } 公共静态无效启用DoubleBuffer(控制) { ListViewExtendedStyles; //阅读当前样式 styles=(ListViewExtendedStyles)SendMessage(control.Handle,(int)ListViewMessages.GetExtendedStyle,0,0); //启用双缓冲区和边框选择 styles |=ListViewExtendedStyles.DoubleBuffer | ListViewExtendedStyles.BorderSelect; //写新文体 SendMessage(control.Handle,(int)ListViewMessages.SetExtendedStyle,0,(int)styles); } 公共静态无效禁用DoubleBuffer(控制) { ListViewExtendedStyles; //阅读当前样式 styles=(ListViewExtendedStyles)SendMessage(control.Handle,(int)ListViewMessages.GetExtendedStyle,0,0); //禁用双缓冲区和边框选择 样式-=样式和ListViewExtendedStyles.DoubleBuffer; 样式-=样式和列表视图ExtendedStyles.BorderSelect; //写新文体 SendMessage(control.Handle,(int)ListViewMessages.SetExtendedStyle,0,(int)styles); } } 我看到这个闪烁不定