2009-12-20 25 views
5

Forse mi manca qualcosa, ma ... Il controllo ListView in Windows 7 mostra un'evidenziazione attorno agli elementi selezionati che assomiglia a un rettangolo traslucido blu 3D (non sto parlando della selezione rettangolo, ma il rettangolo attorno agli elementi selezionati effettivi). Mostra anche un rettangolo più chiaro quando si posiziona il mouse sopra gli oggetti..NET ListView e Windows 7

Tuttavia, quando uso il ListView in WinForms (anche quando il doppio buffer), gli elementi selezionati hanno solo uno sfondo blu chiaro (e nessuno sfondo di passaggio del mouse) che sembra molto meno professionale di, diciamo, l'elenco in Explorer.

Qualcuno sa quale funzione API segreto dovrei chiamare per rendere l'aspetto ListView .NET in linea con il resto del sistema operativo?

Ad esempio, ecco una delle mie applicazioni scritte in C++, utilizzando un controllo ListView standard in Windows 7: (notare l'evidenziazione e librarsi rettangolo)

alt text

E qui è una riscrittura di quella applicazione in C# con WinForms: (si noti il ​​punto culminante greggio e non hover)

alt text

risposta

12

OK, ho totalmente capito, e questo può aiutare gli altri che sono infastiditi da questo problema.

Ho iniziato notando che il controllo ListView in C++ Builder sembra "corretto" in Windows 7, quindi ho cercato nel codice sorgente del VCL di vedere che tipo di magia stavano facendo per rendere l'aspetto di ListView come il controllo elenco in Windows Explorer. Mi sono imbattuto in una riga di codice che sembrava promettente:

SetWindowTheme(Handle, 'explorer', nil); 

Dalla documentazione SDK, questa funzione "causa una finestra per utilizzare un diverso insieme di informazioni di stile visivo della sua classe utilizza normalmente."

Così, ho provato invocando questa funzione sul mio WinForms controllo ListView:

[DllImport("uxtheme.dll", CharSet = CharSet.Unicode)] 
public static extern int SetWindowTheme(IntPtr hWnd, String pszSubAppName, String pszSubIdList); 


SetWindowTheme(myListView.Handle, "explorer", null); 

... e, per Dio, ha funzionato! Il ListView sembra finalmente appartenere al resto del sistema operativo! Grazie, Borland Inprise Embarcadero! Sei davvero buono per qualcosa!

0

edit: ora si sta lavorando anche per me, la firma esatta è:

<DllImport("uxtheme.dll", 
    BestFitMapping:=False, 
    CharSet:=CharSet.Unicode, 
    EntryPoint:="#136", 
    CallingConvention:=CallingConvention.Winapi)> 
    Private Shared Function SetWindowsTheme(ByVal handle As IntPtr, ByVal app As String, ByVal id As String) As Integer 
     ' Leave function empty - DLLImport attribute forwards calls to the right function 
    End Function 


Public Shared Sub MakeControlLookBeautiful(ByVal c As Windows.Forms.Control) 
    SetWindowsTheme(c.Handle, "explorer", Nothing) 
End Sub 

:)

1
Imports System.Runtime.InteropServices 

Public Class Form1 
    <DllImport("uxtheme", CharSet:=CharSet.Unicode)> _ 
    Public Shared Function SetWindowTheme(ByVal hWnd As IntPtr, ByVal textSubAppName As String, ByVal textSubIdList As String) As Integer 
    End Function 

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 
     SetWindowTheme(lst.Handle, "explorer", Nothing) 
    End Sub 
End Class 

Il codice di cui sopra funzionerà come un campione ...