3

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

Nathan McCoy
  • 3,092
  • 1
  • 24
  • 46

2 Answers2

2

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.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • This works but I have an odd error. When hovering over a row for the first time without clicking, right after the function `e.DrawText()` is called in `listView1_DrawItem()` the other subitems disappear. The only thing that remains is the first column. This doesn't happen again after clicking on a row once. Any suggestions? – Nathan McCoy May 06 '13 at 14:05
  • No idea. I suspect an exception, look in the Output window. – Hans Passant May 06 '13 at 14:07
  • I still had the original test code up, it works just fine, even with HoverSelection set to True. Good luck with it. – Hans Passant May 06 '13 at 14:18
  • 1
    @son_of_fire did you ever figure out the subitems disappearing, I am having the same issue? – maccettura Aug 22 '14 at 20:08
1

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);
    }
}
Max
  • 12,622
  • 16
  • 73
  • 101
  • are you sure? this user has the opposite issue. http://stackoverflow.com/questions/9642281/listview-selection-rectangle . – Nathan McCoy May 06 '13 at 12:04
  • No he has the same, he also wants to change his selection look to something else(Windows explorer style in this case) you want to make it transparant and just highlight the borders. – Max May 06 '13 at 12:06
  • well in either event, the "selection rectangle" shows up on that question, while it is not present on my c#/listview tests. If a "selection rectangle" can be shown, i can override other aspects of coloring the rows. – Nathan McCoy May 06 '13 at 12:10
  • thanks for the idea, but it doesn't seem to work. your claim is that the default theme influences the behaviour but after changing the theme i see no change to my listview such as the addition of a "selection rectangle". therefore when using your class i do not see any change also. maybe there is a setting I am overlooking? any other ideas? thanks for the help! – Nathan McCoy May 06 '13 at 12:27