Flickering in ListView control (OwnerDraw, Virtual)

前端 未结 3 1853
长情又很酷
长情又很酷 2021-02-07 23:08

This question might be considered a follow-up to Flickering in listview with ownerdraw and virtualmode.

I\'ve got a ListView control in Virtu

相关标签:
3条回答
  • 2021-02-07 23:34

    At least for double buffering for OnDrawItem, it is incorrect that there is a bug, but it is a little bit stupid: there is a protected attribute you can set, but you need to override the ListView. I created this kind of class:

    public class MyListView : ListView
    {
        public MyListView()
            : base()
        {
            DoubleBuffered = true;
        }
    }
    

    And then in my MyForm.Designer.cs file I change the instantiation of the ListView with the following line:

    private ListView myListView;
    
    this.myListView = new MyListView();
    

    And OnDrawItem will work like a charm!

    0 讨论(0)
  • 2021-02-07 23:51

    Like This Answer in Here, though not sure but,

    I think that ListView.BeginUpdate() and ListView.EndUpdate() will solve the problem.

    MSDN Thread about This

    Maybe In This Way :

    protected override void OnDrawItem(DrawListViewItemEventArgs eventArgs)
    {
        ListView.BeginUpdate();
        //Do Works Here
        ListView.EndUpdate();
    }
    

    Update

    Another Alternative may be using a new Thread in BackgroundWorker to Update the ListView... I implemented this along with BeginUpdate()/EndUpDate() in my application and found it relatively faster than only the BeginUpdate()/EndUpDate()..

    Update

    I found another working Solution at SO, a Helper class provided by 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);
        }
    }
    
    0 讨论(0)
  • 2021-02-07 23:57

    I've seen this flickering issue with ListView control in any custom rendering event handlers (DrawItem, DrawSubItem). I tried BeginUpdate()/EndUpdate() and double buffering with no success. I think .NET triggers additional WM_PAINT to all columns to the right of the custom drawn column.

    However I found this workaround to a single custom rendered column ListView. It works just fine!

    1. In the columnheader editor, set the custom drawn column as the last column
    2. Change the "DisplayIndex" of the position you want

    This should solve the flickering in mouseover or run-time rendering.

    0 讨论(0)
提交回复
热议问题