2010-04-22 26 views
8

Sto utilizzando SetWindowTheme e SendMessage per fare in modo che un listview .net assomigli ad un listview stile vista, ma il controllo .net ha ancora un bordo di selezione tratteggiato attorno all'elemento selezionato:Come rimuovere il bordo di selezione su un ListViewItem

listview

elementi selezionati nel listview explorer non hanno quel confine intorno a loro. Come posso rimuoverlo?

Esplora risorse:

windows explorer

Edit: Soluzione:

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

risposta

10

La soluzione Telanors ha funzionato per me. Ecco una versione leggermente più autonoma.

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

Vuol impostando la proprietà su false ListView.ShowFocusCues aiuto?

+0

Sembra che questa proprietà è impostata su false per impostazione predefinita. – Ucodia

+5

Mentre lo ShowFocusCues stesso non funzionava, il WM_CHANGEUISTATE elencato su quella pagina MSDN mi portava alla risposta giusta. Inviando un messaggio WM_CHANGEUISTATE con UISF_HIDEFOCUS sono stato in grado di eliminare il rettangolo di attivazione. – Telanor

+0

@Telanor, Si prega di aggiornare la domanda con un codice di stub della soluzione – Joe

1

Non sembra che esista un modo particolare per modificare gli stili ListViewItem utilizzando Windows Form.

A volte non è possibile modificare alcuni comportamenti di controllo Win32 utilizzando il codice gestito. L'unico modo è di fare qualche P/Invoke per modificare comportamenti specifici. Trovo che sia davvero complicato ma non hai altra scelta. Ho spesso affrontato questa situazione durante lo sviluppo di interfacce utente di Windows Mobile (giustamente con ListView).

Quindi non ho una risposta diretta alla tua domanda, ma sono abbastanza sicuro che se non è possibile utilizzare Windows Form, puoi sicuramente farlo con P/Invoke. Gli unici indizi che posso darvi:

2

impostando la proprietà HotTracking true nasconde il rettangolo di attivazione. Questo Repro-ed allo stile Explorer sulla mia macchina 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); 
} 

Attenzione che ottenere gli elementi sottolineati è un effetto collaterale.

2

Facendo questo il modo in cui NON P/Invoke ...

ignorare la controllo ListView e aggiungere il seguente:

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