Как я могу удалить границу выделения на ListViewItem - PullRequest
9 голосов
/ 22 апреля 2010

Я использую SetWindowTheme и SendMessage, чтобы сделать вид списка .net похожим на вид списка в стиле Vista, но элемент управления .net все еще имеет пунктирную рамку выделения вокруг выделенного элемента:

listview

Выбранные элементы в списке обозревателя не имеют этой границы вокруг них.Как я могу удалить его?

Проводник Windows:

windows explorer

Редактировать: Решение:

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

Ответы [ 6 ]

11 голосов
/ 02 апреля 2013

Решение 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);
    }
}
3 голосов
/ 16 января 2015

Делая это NON P / Invoke way ...

Переопределите свой элемент управления 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);
}
3 голосов
/ 22 апреля 2010

Если для свойства HotTracking установлено значение true, прямоугольник фокуса скрывается. Это воспроизвело стиль Explorer на моей машине с Win7:

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

Остерегайтесь того, что подчеркивание предметов является побочным эффектом.

2 голосов
/ 22 апреля 2010

Имеет ли значение свойства ListView.ShowFocusCues значение false?

1 голос
/ 22 апреля 2010

Не похоже, что есть особый способ изменить стили ListViewItem с помощью Windows Forms.

Иногда невозможно изменить поведение некоторых элементов управления Win32 с помощью управляемого кода.Единственный способ - сделать P / Invoke, чтобы изменить специфическое поведение.Я считаю это действительно сложно, но у вас нет другого выбора.Я часто сталкивался с такой ситуацией при разработке пользовательских интерфейсов Windows Mobile (справедливо с ListView).

Так что у меня нет прямого ответа на ваш вопрос, но я уверен, что если это невозможно с помощью Windows Forms, вы, безусловно, можете сделать это с помощью P / Invoke.Единственные подсказки, которые я могу вам дать:

0 голосов
/ 14 мая 2018

Я знаю, что это довольно старая версия Windows Forms устарела, но она все еще используется и остается проблемой. Хуже того, ни одно из этих решений не является элегантным, а некоторые даже не работают вообще.

Вот очень простое решение, когда вы создаете свой собственный элемент управления, который наследует 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);
    }
}
...