Solved

ListView with combobox

Posted on 2009-07-16
6
2,412 Views
Last Modified: 2012-05-07
I have managed to create everything but I am still missing how to add a combobox to my listview
Please show me how to do this.

I have been to alot of webpages and I cant seem to get it running. So I dont need links to webpages. I do need someone to show how to do it.

My combobox name is teleComboBox
in my Contact class is all the phones I want to add int this: private List<Phone> m_phone;
listView1.Clear();

 

            // Used for creating listview items.

            ListViewItem listviewitem;

 

            //ListViewItem subItem = new ListViewItem();

            listView1.Columns.Add("FirstName");

            listView1.Columns.Add("LastName");

            listView1.Columns.Add("E-mail");

            listView1.Columns.Add("Phonenumbers");

 

            // Ensure that the view is set to show details.

            listView1.View = View.Details;

            listView1.FullRowSelect = true;

 

            // Create some listview items consisting of first and last names.

            foreach (Contact contact in contactManager.Contacts)

            {

                listviewitem = new ListViewItem(contact.FirstName);

                listviewitem.SubItems.Add(contact.LastName);

                listviewitem.SubItems.Add(contact.MyEmail.Personal);

 

                //listviewitem.SubItems.Add(contact.Telephone.ToString());

 

                this.listView1.Items.Add(listviewitem);

 

 

            }

Open in new window

0
Comment
Question by:Mickeys
6 Comments
 
LVL 13

Expert Comment

by:drypz
Comment Utility
hi! you may refer to this link

http://support.microsoft.com/kb/320344
0
 

Author Comment

by:Mickeys
Comment Utility
been there. Didnt get it to work. So please...no more links. Just show me how to do it.
0
 
LVL 29

Expert Comment

by:Gautham Janardhan
Comment Utility
are u using WPF ?
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

Author Comment

by:Mickeys
Comment Utility
I have no idea. I have created a windows form....am I using it then? (VS2008)
0
 
LVL 8

Expert Comment

by:rambovn
Comment Utility
just follow the link http://support.microsoft.com/kb/320344 and post your problem here
It is a good tutorial.
0
 
LVL 29

Accepted Solution

by:
Gautham Janardhan earned 500 total points
Comment Utility

/* ListViewEx.cs 

 * This file contains the definition of the class ListViewEx, which is a

 * reusable class derived from ListView. 

*/
 

#region Namespaces

using System;

using System.Drawing;

using System.Collections;

using System.Diagnostics;

using System.Windows.Forms;

using System.ComponentModel;

using System.Collections.Specialized;

using System.Runtime.InteropServices;

#endregion
 

namespace CustomListView

{

	/// <summary>

	/// Class derived from ListView to give ability to display controls

	/// like TextBox and Combobox

	/// </summary>

	public class ListViewEx : ListView

	{

		#region The RECT structure

		/// <summary>

		/// This struct type will be used as the oupput 

		/// param of the SendMessage( GetSubItemRect ). 

		/// Actually it is a representation for the strucure 

		/// RECT in Win32

		/// </summary>

		[StructLayout(LayoutKind.Sequential)]

		internal struct RECT

		{

			public int left;

			public int top;

			public int right;

			public int bottom;

		}

		#endregion
 

		#region Win32 Class

		/// <summary>

		/// Summary description for Win32.

		/// </summary>

		internal class Win32

		{

			/// <summary>

			/// This is the number of the message for getting the sub item rect.

			/// </summary>

			public const int LVM_GETSUBITEMRECT  = (0x1000) + 56;
 

			/// <summary>

			/// As we are using the detailed view for the list,

			/// LVIR_BOUNDS is the best parameters for RECT's 'left' member.

			/// </summary>

			public const int LVIR_BOUNDS = 0;
 

			/// <summary>

			/// Sending message to Win32

			/// </summary>

			/// <param name="hWnd">Handle to the control</param>

			/// <param name="messageID">ID of the message</param>

			/// <param name="wParam"></param>

			/// <param name="lParam"></param>

			/// <returns></returns>

			[DllImport("user32.dll", SetLastError=true)]

			public static extern int SendMessage(IntPtr hWnd, int messageID, int wParam , ref RECT lParam);

		}

		#endregion
 

		#region SubItem Class

		/// <summary>

		/// This class is used to represent 

		/// a listview subitem.

		/// </summary>

		internal class SubItem

		{

			/// <summary>

			/// Item index

			/// </summary>

			public readonly int row;
 

			/// <summary>

			/// Subitem index

			/// </summary>

			public readonly int col;
 

			/// <summary>

			/// Parameterized contructor

			/// </summary>

			/// <param name="row"></param>

			/// <param name="col"></param>

			public SubItem( int row, int col )

			{

				this.row = row;

				this.col = col;

			}

		}

		#endregion
 

		#region Variables & Properties

		/// <summary>

		/// If this variable is true, then 

		/// subitems for an item is added 

		/// automatically, if not present.

		/// </summary>

		private bool addSubItem = false;

		public bool AddSubItem 

		{

			set

			{

				this.addSubItem = value;

			}

		}
 

		/// <summary>

		/// This variable tells whether the combo box 

		/// is needed to be displayed after its selection

		/// is changed

		/// </summary>

		private bool hideComboAfterSelChange = false;

		public bool HideComboAfterSelChange

		{

			set

			{

				this.hideComboAfterSelChange = value;

			}

		}
 

		/// <summary>

		/// Represents current row

		/// </summary>

		private int row = -1;
 

		/// <summary>

		/// Represents current column

		/// </summary>

		private int col = -1;
 

		/// <summary>

		/// Textbox to display in the editable cells

		/// </summary>

		private TextBox textBox = new TextBox();
 

		/// <summary>

		/// Combo box to display in the associated cells

		/// </summary>

		private ComboBox combo = new ComboBox();
 

		/// <summary>

		/// This is a flag variable. This is used to determine whether

		/// Mousebutton is pressed within the listview

		/// </summary>

		private bool mouseDown = false;
 

		/// <summary>

		/// To store, subitems that contains comboboxes and text boxes

		/// </summary>

		private Hashtable customCells = new Hashtable();

		#endregion
 

		#region Methods

		/// <summary>

		/// Constructor

		/// </summary>

		public ListViewEx()

		{

			// Initialize controls

			this.InitializeComponent();

		}
 

		/// <summary>

		/// Initializes the text box and combo box

		/// </summary>

		private void InitializeComponent()

		{

			// Text box

			this.textBox.Visible = false;

			textBox.BorderStyle = BorderStyle.FixedSingle;

			this.textBox.Leave += new EventHandler(textBox_Leave);
 

			// Combo box

			this.combo.Visible = false;

			this.Controls.Add( this.textBox );

			this.Controls.Add( this.combo );

			this.combo.DropDownStyle = ComboBoxStyle.DropDownList;

			this.combo.SelectedIndexChanged += new EventHandler(combo_SelectedIndexChanged);

		}
 

		/// <summary>

		/// This method will send LVM_GETSUBITEMRECT message to 

		/// get the current subitem bouds of the listview

		/// </summary>

		/// <param name="clickPoint"></param>

		/// <returns></returns>

		private RECT GetSubItemRect(Point clickPoint)

		{

			// Create output param

			RECT subItemRect = new RECT();
 

			// Reset the indices

			this.row = this.col = -1;

			

			// Check whether there is any item at the mouse point

			ListViewItem item = this.GetItemAt(clickPoint.X, clickPoint.Y);
 

			if(item != null )

			{

				for(int index = 0; index < this.Columns.Count; index++)

				{				

					// We need to pass the 1 based index of the subitem.

					subItemRect.top = index + 1; 
 

					// To get the boudning rectangle, as we are using the report view

					subItemRect.left = Win32.LVIR_BOUNDS;

					try

					{

						// Send Win32 message for getting the subitem rect. 

						// result = 0 means error occuured

						int result = Win32.SendMessage(this.Handle, Win32.LVM_GETSUBITEMRECT, item.Index, ref subItemRect);

						if( result != 0 )

						{

							// This case happens when items in the first columnis selected.

							// So we need to set the column number explicitly

							if(clickPoint.X < subItemRect.left)

							{

								this.row = item.Index;

								this.col= 0;

								break;

							}

							if(clickPoint.X >= subItemRect.left & clickPoint.X <= 

								subItemRect.right)

							{

								this.row = item.Index;

								// Add 1 because of the presence of above condition

								this.col = index + 1;

								break;

							}

						}

						else

						{

							// This call will create a new Win32Exception with the last Win32 Error.

							throw new Win32Exception();

						}

					}

					catch( Win32Exception ex )

					{

						Trace.WriteLine( string.Format("Exception while getting subitem rect, {0}", ex.Message ));

					}

				}

			}			

			return subItemRect;

		}
 

		/// <summary>

		/// Set a text box in a cell

		/// </summary>

		/// <param name="row">The 0-based index of the item.  Give -1 if you

		///					  want to set a text box for every items for a

		///					  given "col" variable.

		///	</param>

		/// <param name="col">The 0-based index of the column. Give -1 if you

		///					  want to set a text box for every subitems for a

		///					  given "row" variable.

		///	</param>

		public void AddEditableCell( int row, int col )

		{

			// Add the cell into the hashtable

			// Value is setting as null because it is an editable cell

			this.customCells[new SubItem( row, col )] = null;

		}
 

		/// <summary>

		/// Set a combobox in a cell

		/// </summary>

		/// <param name="row"> The 0-based index of the item.  Give -1 if you

		///					   want to set a combo box for every items for a

		///					   given "col" variable.

		///	</param>

		/// <param name="col"> The 0-based index of the column. Give -1 if you

		///					   want to set a combo box for every subitems for a

		///					   given "row" variable.

		///	</param>

		/// <param name="data"> Items of the combobox 

		/// </param>

		public void AddComboBoxCell( int row, int col, StringCollection data )

		{

			// Add the cell into the hashtable

			// Value for the hashtable is the combobox items

			this.customCells[new SubItem( row, col )] = data;

		}
 

		/// <summary>

		/// Set a combobox in a cell

		/// </summary>

		/// <param name="row"> The 0-based index of the item.  Give -1 if you

		///					   want to set a combo box for every items for a

		///					   given "col" variable.

		///	</param>

		/// <param name="col"> The 0-based index of the column. Give -1 if you

		///					   want to set a combo box for every subitems for a

		///					   given "row" variable.

		///	</param>

		/// <param name="data"> Items of the combobox 

		/// </param>

		public void AddComboBoxCell( int row, int col, string[] data )

		{

			try

			{

				StringCollection param = new StringCollection();

				param.AddRange( data );

				this.AddComboBoxCell( row, col, param );

			}

			catch( Exception ex )

			{

				Trace.WriteLine( ex.ToString());

			}

		}
 

		/// <summary>

		/// This method will display the combobox

		/// </summary>

		/// <param name="location">Location of the combobox</param>

		/// <param name="sz">Size of the combobox</param>

		/// <param name="data">Combobox items</param>

		private void ShowComboBox( Point location, Size sz, StringCollection data )

		{

			try

			{

				// Initialize the combobox

				combo.Size = sz;

				combo.Location = location;

				// Add items

				combo.Items.Clear();

				foreach( string text in data )

				{

					combo.Items.Add( text );

				}			

				// Set the current text, take it from the current listview cell

				combo.Text = this.Items[row].SubItems[col].Text;

				// Calculate and set drop down width

				combo.DropDownWidth = this.GetDropDownWidth(data);

				// Show the combo

				combo.Show();

			}

			catch( ArgumentOutOfRangeException )

			{

				// Sink

			}

		}
 

		/// <summary>

		/// This method will display the textbox

		/// </summary>

		/// <param name="location">Location of the textbox</param>

		/// <param name="sz">Size of the textbox</param>

		private void ShowTextBox( Point location, Size sz )

		{

			try

			{

				// Initialize the textbox

				textBox.Size = sz;

				textBox.Location = location;

				// Set text, take it from the current listview cell

				textBox.Text = this.Items[row].SubItems[col].Text;

				// Shopw the text box

				textBox.Show();

				textBox.Focus();

			}

			catch( ArgumentOutOfRangeException )

			{

				// Sink

			}

		}
 

		/// <summary>

		/// 

		/// </summary>

		/// <param name="e"></param>

		protected override void OnMouseUp ( MouseEventArgs e)

		{

			try

			{

				// Hide the controls

				this.textBox.Visible = this.combo.Visible = false;
 

				// If no mouse down happned in this listview, 

				// no need to show anything

				if( !mouseDown )

				{

					return;

				}
 

				// The listview should be having the following properties enabled

				// 1. FullRowSelect = true

				// 2. View should be Detail;

				if( !this.FullRowSelect || this.View != View.Details )

				{

					return;

				}
 

				// Reset the mouse down flag

				mouseDown = false;
 

				// Get the subitem rect at the mouse point.

				// Remeber that the current row index and column index will also be

				// Modified within the same method

				RECT rect = this.GetSubItemRect( new Point( e.X, e.Y ));

			

				// If the above method is executed with any error,

				// The row index and column index will be -1;

				if( this.row != -1 && this.col != -1 )

				{

					// Check whether combobox or text box is set for the current cell

					SubItem cell = GetKey(new SubItem(this.row, this.col ));
 

					if( cell != null)

					{

						// Set the size of the control(combobox/editbox)

						// This should be composed of the height of the current items and

						// width of the current column

						Size sz = new Size(this.Columns[col].Width, Items[row].Bounds.Height );
 

						// Determine the location where the control(combobox/editbox) to be placed

						Point location = col == 0 ? new Point(0, rect.top) : new Point( rect.left, rect.top);

					

						ValidateAndAddSubItems();
 

						// Decide which conrol to be displayed.

						if(this.customCells[cell] == null )

						{

							this.ShowTextBox( location, sz );

						}

						else

						{

							this.ShowComboBox( location, sz, (StringCollection) this.customCells[cell] );

						}

					}

				}

			}

			catch( Exception ex )

			{

				Trace.WriteLine( ex.ToString());

			}

		}
 

		/// <summary>

		/// 

		/// </summary>

		private void ValidateAndAddSubItems()

		{

			try

			{

				while( this.Items[this.row].SubItems.Count < this.Columns.Count && this.addSubItem )

				{

					this.Items[this.row].SubItems.Add("");

				}

			}

			catch( Exception ex )

			{

				Trace.WriteLine( ex.ToString());

			}

		}
 

		/// <summary>

		/// This message will get the largest text from the given

		/// stringarray, and will calculate the width of a control which 

		/// will contain that text.

		/// </summary>

		/// <param name="data"></param>

		/// <returns></returns>

		private int GetDropDownWidth( StringCollection data )

		{

			// If array is empty just return the combo box width

			if( data.Count == 0 )

			{

				return this.combo.Width;

			}

			

			// Set the first text as the largest

			string maximum = data[0];
 

			// Now iterate thru each string, to findout the

			// largest

			foreach( string text in data )

			{

				if( maximum.Length <  text.Length )

				{

					maximum = text;

				}

			}

			// Calculate and return the width .

			return (int)(this.CreateGraphics().MeasureString( maximum , this.Font ).Width);

		}
 

		/// <summary>

		/// For this method, we will get a Subitem. 

		/// Then we will iterate thru each of the keys and will 

		/// check whther any key contains the given cells row/column.

		/// If it is not found we will check for -1 in any one

		/// </summary>

		/// <param name="cell"></param>

		/// <returns></returns>

		private SubItem GetKey( SubItem cell )

		{

			try

			{

				foreach( SubItem key in this.customCells.Keys )

				{

					// Case 1: Any particular cells is  enabled for a control(Textbox/combobox)

					if( key.row == cell.row && key.col == cell.col )

					{

						return key;

					}

						// Case 2: Any particular column is  enabled for a control(Textbox/combobox)

					else if( key.row == -1 && key.col == cell.col )

					{

						return key;

					}

						// Entire col for a row is is  enabled for a control(Textbox/combobox)

					else if( key.row == cell.row && key.col == -1 )

					{

						return key;

					}

						// All cells are enabled for a control(Textbox/combobox)

					else if( key.row == -1 && key.col == -1 )

					{

						return key;

					}

				}

			}

			catch( Exception ex )

			{

				Trace.WriteLine( ex.ToString());

			}

			return null;

		}
 

		/// <summary>

		/// 

		/// </summary>

		/// <param name="e"></param>

		protected override void OnMouseDown(MouseEventArgs e)

		{

			try

			{

				// Mouse down happened inside listview

				mouseDown = true;
 

				// Hide the controls

				this.textBox.Hide();

				this.combo.Hide();

			}

			catch( Exception ex )

			{

				Trace.WriteLine( ex.ToString());

			}

		}
 

		/// <summary>

		/// This event handler wll set the current text in the textbox

		/// as the listview's current cell's text, while the textbox 

		/// focus is lost

		/// </summary>

		/// <param name="sender"></param>

		/// <param name="e"></param>

		private void textBox_Leave(object sender, EventArgs e)

		{

			try

			{

				if( this.row != -1 && this.col != -1 )

				{

					this.Items[row].SubItems[col].Text = this.textBox.Text;

					this.textBox.Hide();

				}

			}

			catch( Exception ex )

			{

				Trace.WriteLine( ex.ToString());

			}

		}
 

		/// <summary>

		/// This event handler wll set the current text in the combobox

		/// as the listview's current cell's text, while the combobox 

		/// selection is changed

		/// </summary>

		/// <param name="sender"></param>

		/// <param name="e"></param>

		private void combo_SelectedIndexChanged(object sender, EventArgs e)

		{

			try

			{

				if( this.row != -1 && this.col != -1 )

				{

					this.Items[row].SubItems[col].Text = this.combo.Text;

					this.combo.Visible = !this.hideComboAfterSelChange;		

				}

			}

			catch( Exception ex )

			{

				Trace.WriteLine( ex.ToString());

			}

		}

		#endregion

	}

}

Open in new window

0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Bit flags and bit flag manipulation is perhaps one of the most underrated strategies in programming, likely because most programmers developing in high-level languages rely too much on the high-level features, and forget about the low-level ones. Th…
Introduction                                                 Was the var keyword really only brought out to shorten your syntax? Or have the VB language guys got their way in C#? What type of variable is it? All will be revealed.   Also called…
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now