2010-04-22 25 views
8

Estoy usando SetWindowTheme y SendMessage para hacer que una vista de lista .net parezca una vista de lista de estilo de vista, pero el control .net todavía tiene un borde de selección punteado alrededor del elemento seleccionado:¿Cómo puedo eliminar el borde de selección en un ListViewItem

listview

artículos seleccionados en la vista de lista explorador no tienen ese borde alrededor de ellos. ¿Como puedo quitarlo?

el Explorador de Windows:

windows explorer

Editar: Solución:

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

Respuesta

10

La solución de Telanors funcionó para mí. Aquí hay una versión un poco más autónoma.

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

¿Tiene establecer la propiedad ListView.ShowFocusCues de ayuda falsa?

+0

Parece que esta propiedad se establece en false de forma predeterminada. – Ucodia

+5

Si bien ShowFocusCues no funcionó, el WM_CHANGEUISTATE enumerado en esa página de MSDN me condujo a la respuesta correcta. Al enviar un mensaje WM_CHANGEUISTATE con UISF_HIDEFOCUS, pude deshacerme del rectángulo de foco. – Telanor

+0

@Telanor, actualice la pregunta con un código auxiliar de su solución – Joe

1

Parece que no hay una forma particular de cambiar los estilos de ListViewItem utilizando Windows Forms.

A veces no hay forma de cambiar algunos comportamientos de control de Win32 utilizando el código administrado. La única forma es hacer un poco de P/Invoke para modificar comportamientos específicos. Encuentro esto realmente complicado pero no tienes otra opción. A menudo me enfrenté a esta situación al desarrollar las IU de Windows Mobile (justamente con ListView).

Así que no tengo una respuesta directa a su pregunta, pero estoy bastante seguro de que si no es posible con Windows Forms, seguramente puede hacerlo con P/Invoke. Las únicas pistas que puedo darle:

2

Establecer la propiedad HotTracking a la verdadera oculta el rectángulo de selección. Esta repro-ed el estilo Explorer en mi máquina 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); 
} 

Tenga en cuenta que conseguir los elementos subrayados es un efecto secundario.

2

Hacer esto el camino NO P/Invoke ...

anular su control ListView y añadir lo siguiente:

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