Overriding the Drawitem event on a WinForm ListView control

后端 未结 1 1211
北海茫月
北海茫月 2021-01-03 05:09

I\'d like my ListView\'s selected item to remain clearly visible when focus is lost (it is a dim grey on Windows 7 ). I did set the HideSelection property to False.

相关标签:
1条回答
  • 2021-01-03 05:52

    You need something like that:

    private void listView1_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
    {
        e.DrawDefault = true;
    }
    
    private void listView1_DrawSubItem(object sender, DrawListViewSubItemEventArgs e)
    {
        const int TEXT_OFFSET = 1;    // I don't know why the text is located at 1px to the right. Maybe it's only for me.
    
        ListView listView = (ListView)sender;
    
        // Check if e.Item is selected and the ListView has a focus.
        if (!listView.Focused && e.Item.Selected)
        {
            Rectangle rowBounds = e.SubItem.Bounds;
            Rectangle labelBounds = e.Item.GetBounds(ItemBoundsPortion.Label);
            int leftMargin = labelBounds.Left - TEXT_OFFSET;
            Rectangle bounds = new Rectangle(rowBounds.Left + leftMargin, rowBounds.Top, e.ColumnIndex == 0 ? labelBounds.Width : (rowBounds.Width - leftMargin - TEXT_OFFSET), rowBounds.Height);
            TextFormatFlags align;
            switch (listView.Columns[e.ColumnIndex].TextAlign)
            {
                case HorizontalAlignment.Right:
                    align = TextFormatFlags.Right;
                    break;
                case HorizontalAlignment.Center:
                    align = TextFormatFlags.HorizontalCenter;
                    break;
                default:
                    align = TextFormatFlags.Left;
                    break;
            }
            TextRenderer.DrawText(e.Graphics, e.SubItem.Text, listView.Font, bounds, SystemColors.HighlightText,
                align | TextFormatFlags.SingleLine | TextFormatFlags.GlyphOverhangPadding | TextFormatFlags.VerticalCenter | TextFormatFlags.WordEllipsis);
        }
        else
            e.DrawDefault = true;
    }
    
    private void listView1_DrawItem(object sender, DrawListViewItemEventArgs e)
    {
        ListView listView = (ListView)sender;
    
        // Check if e.Item is selected and the ListView has a focus.
        if (!listView.Focused && e.Item.Selected)
        {
            Rectangle rowBounds = e.Bounds;
            int leftMargin = e.Item.GetBounds(ItemBoundsPortion.Label).Left;
            Rectangle bounds = new Rectangle(leftMargin, rowBounds.Top, rowBounds.Width - leftMargin, rowBounds.Height);
            e.Graphics.FillRectangle(SystemBrushes.Highlight, bounds);
        }
        else
            e.DrawDefault = true;
    }
    

    EDIT: Improved for View = View.Details and FullRowSelect = true.
    EDIT2: Different alignment types of column are taken into account, and also auto-ellipsis flag was added.

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