2009-12-20 20 views
5

Tal vez me falta algo, pero ... El control ListView en Windows 7 muestra un resaltado alrededor de los elementos seleccionados que se parece a un rectángulo translúcido azul 3D (no estoy hablando de la selección rectángulo, pero el rectángulo alrededor de los elementos seleccionados reales). Incluso muestra un rectángulo más claro al pasar por encima de los elementos..NET ListView y Windows 7

Sin embargo, cuando uso el ListView en WinForms (incluso con doble amortiguación), los elementos seleccionados solo tienen un fondo azul claro (y sin fondo) que se ve mucho menos profesional que, por ejemplo, la lista en el Explorador.

¿Alguien sabe a qué función API secreta debo llamar para que el .NET ListView se vea en línea con el resto del sistema operativo?

Por ejemplo, aquí es una de mis aplicaciones escritas en C++, utilizando un control ListView estándar en Windows 7: (nótese el punto culminante y se ciernen rectángulo)

alt text

Y aquí es una reescritura de ese aplicación en C# con Windows Forms: (note el punto culminante crudo y sin vuelo estacionario)

alt text

Respuesta

12

OK, estoy totalmente de lo descubrí, y esto puede ayudar a otros que son incomodados por este problema.

Comencé por notar que el control ListView en C++ Builder parece "correcto" en Windows 7, así que busqué en el código fuente de la VCL para ver qué tipo de magia están haciendo para que LookView como el control de lista en el Explorador de Windows. Me encontré con una línea de código que parecía prometedor:

SetWindowTheme(Handle, 'explorer', nil); 

De la documentación del SDK, esta función "Provoca una ventana a utilizar un conjunto diferente de información de estilo visual que utiliza su clase con normalidad".

tanto, he intentado invocar esta función en mi Windows Forms control ListView:

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


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

... y, por Dios, funcionó! El ListView finalmente parece que pertenece con el resto del sistema operativo. Gracias, Borland Inprise Embarcadero! ¡Realmente eres bueno para algo!

0

edición: ahora se está trabajando para mí también, la firma exacta es:

<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 

El código anterior funcionará como un campeón ...