Reputation: 7720
Maybe I'm missing something, but... The ListView control in Windows 7 displays a highlight around selected items that looks like a 3D blue translucent rectangle (I'm not talking about the selection rectangle, but the rectangle around the actual selected items). It even shows a lighter rectangle when hovering over items.
However, when I use the ListView in WinForms (even when double-buffered), the selected items just have a plain blue background (and no hover background) which looks much less professional than, say, the list in Explorer.
Does anyone know what secret API function I should call to make the .NET ListView look in line with the rest of the OS?
For example, here is one of my applications written in C++, using a standard ListView control in Windows 7: (notice the highlight and hover rectangle)
And here is a rewrite of that application in C# with WinForms: (notice the crude highlight and no hover)
Upvotes: 5
Views: 3502
Reputation: 51
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
The above code will work like a champ...
Upvotes: 1
Reputation: 9134
edit: now it is working for me too, the exact signature is:
<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
:)
Upvotes: 0
Reputation: 7720
OK, I totally figured it out, and this may help others who are bothered by this issue.
I began by noticing that the ListView control in C++Builder looks "correct" under Windows 7, so I looked in the source code for the VCL to see what kind of magic they're doing to make the ListView look like the list control in Windows Explorer. I stumbled on one line of code that looked promising:
SetWindowTheme(Handle, 'explorer', nil);
From the SDK documentation, this function "Causes a window to use a different set of visual style information than its class normally uses."
So, I tried invoking this function on my WinForms ListView control:
[DllImport("uxtheme.dll", CharSet = CharSet.Unicode)]
public static extern int SetWindowTheme(IntPtr hWnd, String pszSubAppName, String pszSubIdList);
SetWindowTheme(myListView.Handle, "explorer", null);
...and, by god, it worked! The ListView finally looks like it belongs with the rest of the OS! Thanks, Borland Inprise Embarcadero! You really are good for something!
Upvotes: 12