nmq
nmq

Reputation: 3154

Remove highlight and add selection border in WinForms ListView C#

After searching a bit, I haven't come across my specific question.

I would like to change the default behavior of ListView selection on a WinForm in C#

I need to do this because I am using custom colors in cells to represent Meta-Information necessecary to the user.

(I am using single row selection only, i.e. MutiSelect = false;)

When I select a row in a ListView the whole row is highlighed blue by default,

Selected Row with Blue Background

Instead I would like know,

How can I outline the border of the row and not change the color(s) of the cells in the row?

As seen in the following

Selected Row without Blue Background and dotted line

Upvotes: 3

Views: 3627

Answers (2)

Hans Passant
Hans Passant

Reputation: 941397

Yes, ListView supports custom drawing by setting the OwnerDraw property to True. That tends to be elaborate but your needs are simple, you can use a lot of the default drawing here. Only when an item is selected do you need something different. The ControlPaint class can draw the dotted rectangle you want. Implement the three Draw event handlers, something like this:

    private void listView1_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e) {
        e.DrawDefault = true;
    }

    private void listView1_DrawItem(object sender, DrawListViewItemEventArgs e) {
        e.DrawBackground();
        e.DrawText();
        if ((e.State & ListViewItemStates.Selected) == ListViewItemStates.Selected) {
            var bounds = e.Bounds;
            bounds.Inflate(-1, -1);
            ControlPaint.DrawFocusRectangle(e.Graphics, bounds);
        }
    }

    private void listView1_DrawSubItem(object sender, DrawListViewSubItemEventArgs e) {
        e.DrawBackground();
        e.DrawText();
        if ((e.ItemState & ListViewItemStates.Selected) == ListViewItemStates.Selected) {
            var bounds = e.Bounds;
            bounds.Inflate(-1, -1);
            ControlPaint.DrawFocusRectangle(e.Graphics, bounds);
        }
    }

Tweak as desired. Do note that you probably also want to implement the MouseDown event so the user can click any sub-item and select the row. It isn't clear anymore that this behaves like a ListView. Use the HitTest() method to implement that.

Upvotes: 2

Max
Max

Reputation: 13338

There is no way to do this, the only way to remove the highlighting is to create a custom listview yourself and override how the selected item is drawn.

EDIT:

give this class a try:

public class NativeListView : System.Windows.Forms.ListView
{
    [DllImport("uxtheme.dll", CharSet = CharSet.Unicode)]
    private extern static int SetWindowTheme(IntPtr hWnd, string pszSubAppName,
                                        string pszSubIdList);

    protected override void CreateHandle()
    {
        base.CreateHandle();

        SetWindowTheme(this.Handle, "explorer", null);
    }
}

Upvotes: 1

Related Questions