How can I remove the selection border on a ListViewItem
Asked Answered
I

7

10

I'm using SetWindowTheme and SendMessage to make a .net listview look like a vista style listview, but the .net control still has a dotted selection border around the selected item:

listview

Selected items in the explorer listview don't have that border around them. How can I remove it?

Windows Explorer:

windows explorer

Edit: Solution:

public static int MAKELONG(int wLow, int wHigh)
{
    int low = (int)LOWORD(wLow);
    short high = LOWORD(wHigh);
    int product = 0x00010000 * (int)high;
    int makeLong = (int)(low | product);
    return makeLong;
}

SendMessage(olv.Handle, WM_CHANGEUISTATE, Program.MAKELONG(UIS_SET, UISF_HIDEFOCUS), 0);
Impound answered 22/4, 2010 at 14:33 Comment(0)
B
12

Telanors solution worked for me. Here's a slightly more self-contained version.

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

public class MyListView : ListView
{
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);

    private const int WM_CHANGEUISTATE = 0x127;
    private const int UIS_SET = 1;
    private const int UISF_HIDEFOCUS = 0x1;

    public MyListView()
    {
        this.View = View.Details;
        this.FullRowSelect = true;

        // removes the ugly dotted line around focused item
        SendMessage(this.Handle, WM_CHANGEUISTATE, MakeLong(UIS_SET, UISF_HIDEFOCUS), 0);
    }

    private int MakeLong(int wLow, int wHigh)
    {
        int low = (int)IntLoWord(wLow);
        short high = IntLoWord(wHigh);
        int product = 0x10000 * (int)high;
        int mkLong = (int)(low | product);
        return mkLong;
    }

    private short IntLoWord(int word)
    {
        return (short)(word & short.MaxValue);
    }
}
Burly answered 2/4, 2013 at 16:4 Comment(0)
D
6

Doing this the NON P/Invoke way...

Override your ListView control and add the following:

protected override void OnSelectedIndexChanged(EventArgs e)
{
    base.OnSelectedIndexChanged(e);
    Message m = Message.Create(this.Handle, 0x127, new IntPtr(0x10001), new IntPtr(0));
    this.WndProc(ref m);
}

protected override void OnEnter(EventArgs e)
{
    base.OnEnter(e);
    Message m = Message.Create(this.Handle, 0x127, new IntPtr(0x10001), new IntPtr(0));
    this.WndProc(ref m);
}
Denise answered 16/1, 2015 at 9:28 Comment(0)
M
3

Setting the HotTracking property to true hides the focus rectangle. This repro-ed the Explorer style on my Win7 machine:

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

class MyListView : ListView {
  public MyListView() {
    this.HotTracking = true;
  }
  protected override void OnHandleCreated(EventArgs e) {
    base.OnHandleCreated(e);
    SetWindowTheme(this.Handle, "explorer", null);
  }
  [DllImport("uxtheme.dll", CharSet = CharSet.Auto)]
  public extern static int SetWindowTheme(IntPtr hWnd, string appname, string subidlist);
}

Beware that getting the items underlined is a side-effect.

Menton answered 22/4, 2010 at 16:37 Comment(0)
B
2

Does setting the ListView.ShowFocusCues property to false help?

Bedfast answered 22/4, 2010 at 14:37 Comment(3)
It seems that this property is set to false by default.Rancid
While the ShowFocusCues itself didn't work, the WM_CHANGEUISTATE listed on that MSDN page led me to the right answer. By sending a WM_CHANGEUISTATE message with UISF_HIDEFOCUS I was able to get rid of the focus rectangle.Impound
@Telanor, Please update the question with a code stub of your solutionVicinage
V
2

I know this is rather old, and Windows Forms is antiquated now, but it's still in use and it's still an issue. Worse, none of these solution are elegant, and some don't even work at all.

Here's a very simple solution, when you create your own control that inherits the ListView, then just override the WndProc to never allow focus. It gets rid of all focus-related dotted selection boxes, item selection, subitem selection, etc...

using System.Windows.Forms;

public partial class NoSelectionListView : ListView
{
    public NoSelectionListView()
    {
        InitializeComponent();
    }

    protected override void WndProc(ref Message m)
    {
        if (m.Msg == 0x0007) //WM_SETFOCUS
        {
            return;
        }
        base.WndProc(ref m);
    }
}
Vocalism answered 14/5, 2018 at 14:28 Comment(0)
R
1

It does not seem that there is a particular way to change ListViewItem styles using Windows Forms.

Sometimes there is no way to change some Win32 control behaviors using managed code. The only way is to do some P/Invoke to modify specific behaviors. I find this really tricky but you have no other choice. I often faced this situation when developing Windows Mobile UIs (justly with ListView).

So I have no direct answer to your question but I am pretty sure that if it is not possible using Windows Forms, you can surely do with P/Invoke. The only clues I can give you:

Rancid answered 22/4, 2010 at 15:41 Comment(0)
A
0

For me turning focus off didn't work until the control was shown.

I did this:

bool HideFocus { get; set; }

bool _hasEnter;

void OnEnter(object sender, EventArgs e)
{
    if (!_hasEnter)
    {
        _hasEnter = true;

        // Selection at startup wont change the actual focus 
        if (this.SelectedIndices.Count > 0)
            this.Items[this.SelectedIndices[0]].Focused = true;

        // Hide focus rectangle if requested 
        if (this.ShowFocusCues && this.HideFocus)
        {
            var lParam1 = MakeLong(UIS_SET, UISF_HIDEFOCUS);

            SendMessage(this.Handle, WM_CHANGEUISTATE, lParam1, 0);
        }
    }
}

See https://mcmap.net/q/1048291/-how-can-i-remove-the-selection-border-on-a-listviewitem above for the MakeLong call.

Also, any selected items before the control is shown, won't set the selection focus.

I basically used the "Set Focus" event to know that the control was shown and that it was actually getting focus, to make the corretions.

Afrikander answered 23/9, 2022 at 18:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.