C# 如何删除ListViewItem上的选择边框
我正在使用SetWindowTheme和SendMessage使.net listview看起来像vista样式的listview,但.net控件在所选项目周围仍有一个虚线选择边框: 资源管理器列表视图中的选定项周围没有边框。我怎样才能删除它 Windows资源管理器: 编辑:解决方案:C# 如何删除ListViewItem上的选择边框,c#,.net,winforms,listview,listviewitem,C#,.net,Winforms,Listview,Listviewitem,我正在使用SetWindowTheme和SendMessage使.net listview看起来像vista样式的listview,但.net控件在所选项目周围仍有一个虚线选择边框: 资源管理器列表视图中的选定项周围没有边框。我怎样才能删除它 Windows资源管理器: 编辑:解决方案: public static int MAKELONG(int wLow, int wHigh) { int low = (int)LOWORD(wLow); short high = LOW
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);
是否将属性设置为false有帮助?似乎没有特定的方法可以使用Windows窗体更改ListViewItem样式 有时无法使用托管代码更改某些Win32控件行为。唯一的方法是执行一些P/Invoke来修改特定的行为。我觉得这很棘手,但你别无选择。我在开发Windows Mobile UI时经常遇到这种情况(与ListView一样) 所以我对你的问题没有直接的答案,但我非常确定,如果不能使用Windows窗体,你当然可以使用p/Invoke。我能给你的唯一线索是:
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);
}
请注意,在项目下面加下划线是一种副作用。Telanros解决方案对我很有效。这里有一个更独立的版本
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);
}
}
以非p/Invoke方式执行此操作 覆盖ListView控件并添加以下内容:
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);
}
我知道这是相当古老的,Windows窗体现在已经过时了,但它仍然在使用,而且仍然是一个问题。更糟糕的是,这些解决方案都不优雅,有些甚至根本不起作用 这里有一个非常简单的解决方案,当您创建自己的继承ListView的控件时,只需重写WndProc以永远不允许焦点。它去掉了所有与焦点相关的虚线选择框、项目选择、子项目选择等
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);
}
}
这个属性似乎默认设置为false。虽然ShowFocusCues本身不起作用,但该MSDN页面上列出的WM_CHANGEUISTATE让我找到了正确的答案。通过使用UISF_HIDEFOCUS发送WM_CHANGEUISTATE消息,我可以摆脱焦点矩形。@Telanor,请用您的解决方案的代码存根更新问题