Solved

ListView with combobox

Posted on 2009-07-16
6
2,529 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
ID: 24867309
hi! you may refer to this link

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

Author Comment

by:Mickeys
ID: 24867401
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
ID: 24867444
are u using WPF ?
0
VMware Disaster Recovery and Data Protection

In this expert guide, you’ll learn about the components of a Modern Data Center. You will use cases for the value-added capabilities of Veeam®, including combining backup and replication for VMware disaster recovery and using replication for data center migration.

 

Author Comment

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

Expert Comment

by:rambovn
ID: 24867608
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
ID: 24867704

/* 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

Windows Server 2016: All you need to know

Learn about Hyper-V features that increase functionality and usability of Microsoft Windows Server 2016. Also, throughout this eBook, you’ll find some basic PowerShell examples that will help you leverage the scripts in your environments!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

This article describes a simple method to resize a control at runtime.  It includes ready-to-use source code and a complete sample demonstration application.  We'll also talk about C# Extension Methods. Introduction In one of my applications…
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
This Micro Tutorial will teach you how to censor certain areas of your screen. The example in this video will show a little boy's face being blurred. This will be demonstrated using Adobe Premiere Pro CS6.
This Micro Tutorial hows how you can integrate  Mac OSX to a Windows Active Directory Domain. Apple has made it easy to allow users to bind their macs to a windows domain with relative ease. The following video show how to bind OSX Mavericks to …

777 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