Click here to Skip to main content
11,920,377 members (40,479 online)
Click here to Skip to main content
Add your own
alternative version


237 bookmarked

Embedding Controls in a ListView

, 30 Dec 2004 CPOL
Rate this:
Please Sign up or sign in to vote.
How to use arbitrary controls in ListView cells.

Sample Image - ListViewEmbeddedControls.jpg


Recently, I stumbled across several requests in various news groups on how to embed controls within a ListView.

There are several owner-drawn ListView controls here on CP, but I wanted to try and bend the standard ListView to my will... Wink | ;)


When you're intending to embed a control in a ListView, you'll have to make sure it's positioned correctly all the time. This can become difficult in several ways:

  • The position and size of a ListViewSubItem can be modified in various ways (for example, resizing the ListView, scrolling, resizing ColumnHeaders, and so on).
  • The default implementation of ListView doesn't have any way to tell you the size and location of ListViewSubItems.
  • Columns can be reordered.
  • ListViewItems can be sorted.

The easiest way to ensure the correct position would be right where the painting occurs, so I decided to override the ListView's WndProc and listen for WM_PAINT as a trigger to calculate the controls' positions.

There may be other, more efficient ways, but then it's really hard to get all the cases in which a control has to be re-positioned. Besides, I didn't find performance problems with a reasonable number of embedded controls.

Obtaining a cell's position and size

That's a little tricky, as the standard ListView won't help you here. It does have a GetItemRect() method, but it only gives you information on the entire ListViewItem. No way to retrieve the bounds of a certain ListViewSubItem here.

Luckily, I've been confronted with the same problem in a previous article of mine (In-place editing of ListView subitems), so the necessary functions were available already.

Basically, I get the height and vertical position of the cell from GetItemRect() and calculate its horizontal position and width from the current ColumnHeaders.

To calculate the left margin of a cell, you just have to sum up the widths of all ColumnHeaders left of your cell, i.e., with indices smaller than your ListViewSubItem's index, right? Unfortunately, not. Columns can be reordered by the users and the ListView's Columns collection doesn't reflect these changes :(

So, I had to resort to interop to get the current display order for the columns. There's a message LVM_GETCOLUMNORDERARRAY the ListView understands to give you the current column order in the form of an int array:

/// <summary>
/// Retrieve the order in which columns appear
/// </summary>
/// <returns>Current display order of column indices</returns>
protected int[] GetColumnOrder()
  IntPtr lPar = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(int)) * Columns.Count);
  IntPtr res = SendMessage(Handle, LVM_GETCOLUMNORDERARRAY, 
               new IntPtr(Columns.Count), lPar);
  if (res.ToInt32() == 0) // Something went wrong
    return null;
  int [] order = new int[Columns.Count];
  Marshal.Copy(lPar, order, 0, Columns.Count);
  return order;

Once I had this array, I could simply sum up the widths of the columns displayed left of the cell in question.

Positioning the embedded control

That's the easiest part. Once I had the correct position and size of a ListViewSubItem, I only had to assign this information to the embedded control's Bounds property in the ListView's Paint event.

What about sorting?

My first tests didn't include sorting the ListView. My first tests also just held the row and column number of the embedded control as a reference to where to put the control.

The problem arose when I allowed the user to sort the ListView. All ListViewItems changed their position but none of the embedded controls did. What had happened?

When a ListView is sorted, the ListViewItems change their position in the Items collection. That's OK, but after sorting, they also have their Index property changed to reflect the current position in the collection and not the position at which they were added originally.

Luckily, this behavior could be fixed easily by adding a reference to the ListViewItem in question to my management structure. Now, I could retrieve the right display position of the ListViewItem as well.

Using the new ListView

To embed a given control in the new, extended ListView, you have two new methods:

public void AddEmbeddedControl(Control c, int col, int row);
public void AddEmbeddedControl(Control c, int col, int row, DockStyle dock);

The second function allows you to specify how the control is positioned and sized in its target cell. Usually, you'd use DockStyle.Fill to let the control use the entire SubItem rectangle (default value if you don't give the dock parameter). If you don't want your control to be resized in both directions, you can specify one of the other DockStyles. If you specify DockStyle.None, your control will not be resized at all and thus might overlap other parts of the ListView.

There are also methods to remove a given control or query the ListView for the control embedded at a certain position.

About the demo

I've added a little demo project so that you can try out the new ListView and its features.

While building the demo, I tried embedding a RichTextBox in the ListView and it worked quite nicely, but I was annoyed to find out that I couldn't keep the RichTextBox from being selected, so I've also included a ReadOnlyRichTextBox class to the demo.

I don't think this qualifies for a separate article, but you can use this ReadOnlyRichTextBox as well with your projects, when you want a label with pretty formatting.

Please feel free to comment on the article and don't forget to vote!

Release History

  • 31.12.2004 V1.0

    Initial release.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Software Developer (Senior) 4voice AG
Germany Germany
No Biography provided

You may also be interested in...

Comments and Discussions

QuestionProblem with button clicking Pin
Member 115915208-Apr-15 11:46
memberMember 115915208-Apr-15 11:46 
QuestionUse Theme Explorer??? Pin
Member 1145224915-Feb-15 2:32
memberMember 1145224915-Feb-15 2:32 
QuestionNice job! Pin
Ravi Bhavnani14-Nov-14 5:50
professionalRavi Bhavnani14-Nov-14 5:50 
QuestionQuestion about ListView messages and Windows Messages Pin
brenntengel@yahoo.fr27-Jun-14 12:31
memberbrenntengel@yahoo.fr27-Jun-14 12:31 
QuestionAmazing Pin
Brian Richardson23-Jun-14 7:25
memberBrian Richardson23-Jun-14 7:25 
GeneralAusgezeichnet! Pin
toneware16-Oct-12 4:52
membertoneware16-Oct-12 4:52 
QuestionJust awesome. Pin
pdoxtader21-Jun-12 5:57
memberpdoxtader21-Jun-12 5:57 
GeneralMy vote of 4 Pin
faley21-Mar-12 1:26
memberfaley21-Mar-12 1:26 
QuestionButton for each row? Pin
Marius Iulian Mihailescu7-Feb-12 11:22
memberMarius Iulian Mihailescu7-Feb-12 11:22 
AnswerRe: Button for each row? Pin
faley21-Mar-12 1:35
memberfaley21-Mar-12 1:35 
QuestionBug in Progress bar display Pin
YKK Reddy28-Dec-11 0:15
memberYKK Reddy28-Dec-11 0:15 
AnswerRe: Bug in Progress bar display Pin
Stuartbaker428-Jan-13 14:41
memberStuartbaker428-Jan-13 14:41 
QuestionGet ListViewItem from Click event Pin
crazyfool21000029-Sep-11 22:57
membercrazyfool21000029-Sep-11 22:57 
QuestionHow do I change the height of the rows? Pin
peter_m_22-Sep-11 8:16
memberpeter_m_22-Sep-11 8:16 
Generalexcellent post Pin
Yael018-Aug-10 14:08
memberYael018-Aug-10 14:08 
GeneralSorting the progressbars Pin
Timotei_Younge21-Jun-10 2:05
memberTimotei_Younge21-Jun-10 2:05 

This is awesome, but could you please explain how the sorting of the embedded controls works? I am not well versed in C# and I am trying to get embedded controls (progressbars) in a ListView to sort but cannot figure it out (using VB .NET) I had a look through the code you made available but am finding it hard to figure out how the sorting of the controls are accomplished.

Questionadding controls to datagridviews Pin
ymaod23-Mar-10 6:17
memberymaod23-Mar-10 6:17 
GeneralMy vote of 1 Pin
Berry1418-Mar-10 5:12
memberBerry1418-Mar-10 5:12 
GeneralHelp... embedded control is not highlighting the selected row Pin
Tien Pham22-Jul-09 6:55
memberTien Pham22-Jul-09 6:55 Pin
mrcouthy11-Jun-09 2:19
membermrcouthy11-Jun-09 2:19 
AnswerRe: Pin
Thomas ST4-Nov-09 2:22
memberThomas ST4-Nov-09 2:22 
QuestionHow can I add multiple button control in a field? Pin
Md. Ali Naser Khan4-Jun-09 0:22
memberMd. Ali Naser Khan4-Jun-09 0:22 
AnswerRe: How can I add multiple button control in a field? Pin
Andrew Courtice7-Jun-11 14:59
memberAndrew Courtice7-Jun-11 14:59 
Questionwhy set Bounds property in the ListView's Paint event? Pin
flyingxu9-Mar-09 17:28
memberflyingxu9-Mar-09 17:28 
GeneralChanging BackColor/ForeColor Pin
mikesinfo8-Dec-08 21:15
membermikesinfo8-Dec-08 21:15 
QuestionDockStyle Pin
tdsuper23-Jun-08 4:41
membertdsuper23-Jun-08 4:41 
AnswerRe: DockStyle Pin
mav.northwind23-Jun-08 6:27
membermav.northwind23-Jun-08 6:27 
GeneralRe: DockStyle Pin
tdsuper23-Jun-08 18:09
membertdsuper23-Jun-08 18:09 
Questionhow to bind data with listview control Pin
jayandrath23-May-08 3:02
memberjayandrath23-May-08 3:02 
GeneralThanks Mav Pin
jchalfant30-Oct-07 4:49
memberjchalfant30-Oct-07 4:49 
GeneralSimple to use, helpful and reliable Pin
Marcus Deecke2-Sep-07 13:51
memberMarcus Deecke2-Sep-07 13:51 
GeneralBug with removing rows with controls Pin
PORTE BLINDEE30-Jul-07 14:34
memberPORTE BLINDEE30-Jul-07 14:34 
GeneralRe: Bug with removing rows with controls [modified] Pin
jiaju_cao2-Aug-07 19:01
memberjiaju_cao2-Aug-07 19:01 
GeneralRe: Bug with removing rows with controls Pin
jchalfant30-Oct-07 12:37
memberjchalfant30-Oct-07 12:37 
GeneralRe: Bug with removing rows with controls Pin
Master Gollom1-Oct-08 3:19
memberMaster Gollom1-Oct-08 3:19 
GeneralProblem with combobox Pin
Louis-Philippe Carignan11-Jul-07 3:09
memberLouis-Philippe Carignan11-Jul-07 3:09 
QuestionScrollBar problem. Pin
Gavrilovici Corneliu30-May-07 22:42
memberGavrilovici Corneliu30-May-07 22:42 
QuestionRe: ScrollBar problem. Pin
Marek Wyborski8-Oct-07 4:59
memberMarek Wyborski8-Oct-07 4:59 
AnswerRe: ScrollBar problem. Pin
Marek Wyborski8-Oct-07 22:54
memberMarek Wyborski8-Oct-07 22:54 
GeneralAwesome Pin
lambn1-Mar-07 18:12
memberlambn1-Mar-07 18:12 
GeneralVery nice. Just a few questions. [modified] Pin
Th3Pr0ph3t12-Feb-07 8:50
memberTh3Pr0ph3t12-Feb-07 8:50 
QuestionWhen changing one ComboBox all other cb r also changed Pin
travellermania17-Jan-07 4:28
membertravellermania17-Jan-07 4:28 
GeneralText inside the button Pin
oeriksen1-Jan-07 11:25
memberoeriksen1-Jan-07 11:25 
GeneralRe: Text inside the button Pin
oeriksen1-Jan-07 13:48
memberoeriksen1-Jan-07 13:48 
GeneralRe: Text inside the button Pin
mav.northwind1-Jan-07 23:55
membermav.northwind1-Jan-07 23:55 
GeneralListViewItem deletion/sorting Pin
Anand Eyunni19-Nov-06 12:45
memberAnand Eyunni19-Nov-06 12:45 
QuestionColumn Heather Font? Pin
k^s13-Oct-06 3:59
memberk^s13-Oct-06 3:59 
QuestionHow work to not Using WinApi32 for Embedding Controls? Pin
shiken3-Sep-06 20:34
membershiken3-Sep-06 20:34 
AnswerRe: How work to not Using WinApi32 for Embedding Controls? Pin
mav.northwind4-Sep-06 9:42
membermav.northwind4-Sep-06 9:42 
GeneralRe: How work to not Using WinApi32 for Embedding Controls? Pin
shiken4-Sep-06 16:40
membershiken4-Sep-06 16:40 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.151120.1 | Last Updated 31 Dec 2004
Article Copyright 2004 by mav.northwind
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid