9

我正在使用 SetWindowTheme 和 SendMessage 使 .net 列表视图看起来像 vista 样式的列表视图,但 .net 控件仍然在所选项目周围有一个虚线选择边框:

列表显示

资源管理器列表视图中的选定项目周围没有边框。我怎样才能删除它?

Windows资源管理器:

Windows资源管理器

编辑:解决方案:

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);
4

6 回答 6

11

Telanors 解决方案对我有用。这是一个稍微独立的版本。

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);
    }
}
于 2013-04-02T16:04:08.697 回答
5

以非 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);
}
于 2015-01-16T09:28:14.157 回答
3

将 HotTracking 属性设置为 true 会隐藏焦点矩形。这在我的 Win7 机器上重现了 Explorer 风格:

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);
}

请注意,将项目加下划线是一种副作用。

于 2010-04-22T16:37:40.377 回答
2

ListView.ShowFocusCues属性设置为 false 有帮助吗?

于 2010-04-22T14:37:30.577 回答
1

似乎没有使用 Windows 窗体更改 ListViewItem 样式的特定方法。

有时无法使用托管代码更改某些 Win32 控件行为。唯一的方法是做一些 P/Invoke 来修改特定的行为。我觉得这真的很棘手,但你别无选择。我在开发 Windows Mobile UI 时经常遇到这种情况(仅使用 ListView)。

所以我无法直接回答您的问题,但我很确定如果无法使用 Windows 窗体,您当然可以使用 P/Invoke。我能给你的唯一线索:

于 2010-04-22T15:41:34.467 回答
1

我知道这已经很老了,而且 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);
    }
}
于 2018-05-14T14:28:02.937 回答