2010-04-22 11 views
8

Używam SetWindowTheme i SendMessage, aby widok listy .net wyglądał jak widok listy w stylu Vista, ale formant .net nadal ma przerywaną ramkę zaznaczenia wokół wybranego elementu:Jak usunąć krawędź zaznaczenia na ListViewItem

listview

Wybrane pozycje w Eksploratorze ListView nie masz tego obramowanie wokół nich. Jak mogę go usunąć?

Windows Explorer:

windows explorer

Edit: Rozwiązanie:

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

Odpowiedz

10

Rozwiązanie Telanors dla mnie zadziałało. Oto nieco bardziej samodzielna wersja.

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

Czy ustawienie właściwości na false pomoc ListView.ShowFocusCues?

+0

Wydaje się, że ta właściwość jest ustawiona na false domyślnie. – Ucodia

+5

Podczas gdy ShowFocusCues sam nie działał, WM_CHANGEUISTATE wymienione na tej stronie MSDN doprowadziło mnie do właściwej odpowiedzi. Wysyłając wiadomość WM_CHANGEUISTATE z UISF_HIDEFOCUS, udało mi się pozbyć prostokąta skupienia. – Telanor

+0

@Telanor, proszę zaktualizować pytanie za pomocą kodu dostępu do swojego rozwiązania – Joe

1

Nie wydaje się, że istnieje określony sposób zmiany stylów ListViewItem przy użyciu formularzy Windows.

Czasami nie ma sposobu na zmianę niektórych zachowań sterujących Win32 za pomocą zarządzanego kodu. Jedynym sposobem jest zrobienie jakiegoś P/Invoke w celu modyfikacji określonych zachowań. Uważam, że to naprawdę trudne, ale nie masz innego wyboru. Często stykałem się z tą sytuacją podczas tworzenia interfejsów Windows Mobile (słusznie z ListView).

Więc nie mam bezpośredniej odpowiedzi na twoje pytanie, ale jestem całkiem pewny, że jeśli nie jest to możliwe za pomocą Windows Forms, na pewno możesz zrobić z P/Invoke. Jedyne wskazówki mogę podać:

2

ustawienie właściwości HotTracking true ukrywa prostokąta ostrości. Ten repro-ed styl Explorer na moim komputerze 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); 
} 

Pamiętaj, że coraz elementy podkreślone jest efektem ubocznym.

2

Spowoduje to sposób NON P/Invoke ...

zastąpią kontroli ListView i dodać następujące:

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