Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I remove the selection border on a ListViewItem

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);
like image 937
Telanor Avatar asked Apr 22 '10 14:04

Telanor


4 Answers

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);
}
like image 147
Matthew Layton Avatar answered Oct 30 '22 05:10

Matthew Layton


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);
    }
}
like image 29
John Suit Avatar answered Sep 25 '22 00:09

John Suit


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);
    }
}
like image 12
Mike Fuchs Avatar answered Oct 30 '22 04:10

Mike Fuchs


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.

like image 3
Hans Passant Avatar answered Oct 30 '22 04:10

Hans Passant