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 selec
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);
}
}
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.
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:
Does setting the ListView.ShowFocusCues property to false help?
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);
}
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);
}
}