A few tips on customizing ListView in WM 6.5

Would you like to have ListView control in your .NET CF application on Windows Mobile 6.5 to have this fancy gradient item selections (they are defined by the current theme on the device)?

The secret is in the extended style LVS_EX_THEME that needs to be applied to a ListView. It could be done by sending LVM_SETEXTENDEDLISTVIEWSTYLE to the control. I've wrapped appropriate P/Invoke calls in the following extention method:

/// <summary>

/// Sets theme style to a listview

/// </summary>

/// <param name="listView">ListView instance</param>

public static void SetThemeStyle(this ListView listView)

{

     // Retreive the current extended style

     int currentStyle = SendMessage(listView.Handle,

                                  (uint)LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0);

    // Assign the LVS_EX_THEM style

     SendMessage(listView.Handle, (uint)LVM_SETEXTENDEDLISTVIEWSTYLE, 0,

currentStyle | LVS_EX_THEME);

           

}

But wait there's more... While looking up the values for the P/Invoke messages in the commctrl.h, my eyes cought the forgotten LVM_SETBKIMAGE message which could be used to assign a background image to a ListView. This is how another extention method would look like:

/// <summary>

/// Sets background image to a listview

/// </summary>

/// <param name="listView">ListView instance.</param>

/// <param name="path">string path to an image.</param>

public static void SetBackgroundImage(this ListView listView, string path)

{

      // Create bitmap

    Bitmap bitmap = new Bitmap(path);

      // Retrieve HBITMAP

      IntPtr hBitmap = bitmap.GetHbitmap();

      // Dispose the managed bitmap

      bitmap.Dispose();

      // Prepare structure

      LVBKIMAGE lvImage = new LVBKIMAGE();

      lvImage.hbm = hBitmap;

      lvImage.ulFlags = LVBKIF_SOURCE_HBITMAP;

      // Assign an image

   SendMessage(listView.Handle, LVM_SETBKIMAGE, 0, ref lvImage);

 }

The SetBackroundImage method should also work on all WM 6.0 - 6.5 devices. 

The way you can use these methods should be pretty obvious:

  this.listView1.SetThemeStyle();

  this.listView1.SetBackgroundImage(@"\My Documents\My Pictures\Water.jpg");

And the resulting screenshot:

 

As usual you can download the demo project that contains all the code including P/Invoke declarations.

 

ListViewCustomize.zip

Comments

  • Anonymous
    December 04, 2009
    Thanks for sharing the magic trick. Dr.Luiji

  • Anonymous
    December 04, 2009
    Thanks for the tip ! Do you know any way to get the "fancy gradient" of selected items in an ownerdrawn list ? Thx in advance, Cocotteseb

  • Anonymous
    December 04, 2009
    No, the themed selection doesn't work for ownerdrawn listview. Either you allow system to draw it or draw everything yourself.

  • Anonymous
    December 16, 2009
    I'm somewhat new to C#, though I've been able to get a good sense of it all in the few weeks I've been working on it. I cannot get the "this" in the parameter to build in VS2005, and have been unable to find any documentation about what you're doing with that call.

  • Anonymous
    December 16, 2009
    It would appear that VS2005 doesn't support extension methods. (It finally made sense what you were doing here) All in all, I got that to work. Your blog looks to have a lot of great pieces of code, looking forward to more.

  • Anonymous
    January 06, 2010
    as i noticed when you are scrolling down your list, the background image also moves and a white space apears. What if i want the backrgound image to be always stable?

  • Anonymous
    August 10, 2010
    if i replace the listview with the listbox, will i get the same result?