2010-04-22 4 views
8

Ich verwende SetWindowTheme und SendMessage, um eine .net-Listenansicht wie eine Listview im Vista-Stil aussehen zu lassen, aber das Steuerelement .net hat immer noch einen gepunkteten Auswahlrahmen um das ausgewählte Element:Wie kann ich den Auswahlrahmen in einem ListViewItem entfernen?

listview

Ausgewählte Elemente im Explorer Listenansicht nicht über diese Grenze um sie herum. Wie kann ich es entfernen?

Windows Explorer:

windows explorer

Edit: Lösung:

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

Antwort

10

Telanor Lösung arbeitete für mich. Hier ist eine etwas in sich geschlossene Version.

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

Hat die ListView.ShowFocusCues Eigenschaft auf false Hilfe einstellen?

+0

Es scheint, dass diese Eigenschaft standardmäßig auf false gesetzt ist. – Ucodia

+5

Während die ShowFocusCues selbst nicht funktionierte, führte das auf dieser MSDN-Seite aufgelistete WM_CHANGEUISTATE zur richtigen Antwort. Durch Senden einer WM_CHANGEUISTATE-Nachricht mit UISF_HIDEFOCUS konnte ich das Fokusrechteck loswerden. – Telanor

+0

@Telanor, Bitte aktualisieren Sie die Frage mit einem Code-Stub Ihrer Lösung – Joe

1

Es scheint nicht, dass es eine bestimmte Möglichkeit gibt, ListViewItem-Stile mithilfe von Windows Forms zu ändern.

Manchmal ist es nicht möglich, einige Win32-Steuerungsverhalten mithilfe von verwaltetem Code zu ändern. Die einzige Möglichkeit besteht darin, P/Invoke durchzuführen, um bestimmte Verhaltensweisen zu ändern. Ich finde das wirklich schwierig, aber du hast keine andere Wahl. Bei der Entwicklung von Windows Mobile-UIs (gerade mit ListView) bin ich oft auf diese Situation gestoßen.

So habe ich keine direkte Antwort auf Ihre Frage, aber ich bin mir ziemlich sicher, dass, wenn es nicht mit Windows Forms möglich ist, Sie sicherlich mit P/Invoke tun können. Die einzigen Hinweise kann ich Ihnen geben:

2

Einstellung der HotTracking Eigenschaft auf true blendet das Fokus-Rechteck. Dies repop-the Explorer-Stil auf meinem Win7-Rechner:

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

Achten Sie darauf, dass das Unterstreichen der Elemente ein Nebeneffekt ist.

2

dies tun die NON P/Invoke Art und Weise ...

Ihre Listview-Steuerelement außer Kraft setzen und fügen Sie den folgenden:

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