Click here to Skip to main content
15,897,181 members
Articles / Programming Languages / C#

TreeListView

Rate me:
Please Sign up or sign in to vote.
4.79/5 (147 votes)
31 Aug 2003Ms-PL5 min read 1.6M   38.5K   436  
A custom control that ties a ListView and a TreeView together
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Runtime.InteropServices.APIs;
using System.Runtime.InteropServices;

namespace System.Windows.Forms
{
	internal class CustomEdit : NativeWindow, IWin32Window
	{
		#region Properties
		private TreeListViewItemEditControlHandle _editorhandle;
		private EditItemInformations _informations;
		private Control _editor;
		new public IntPtr Handle
		{
			get{return base.Handle;}
		}
		private TreeListView _treelistview;
		#endregion
		#region Constructor & Destructor
		private CustomEdit(){}
		public CustomEdit(IntPtr handle, TreeListView treelistview, Control editor)
		{
			_treelistview = treelistview;
			_informations = _treelistview.EditedItem;
			if(editor == null) _editor = new TextBox();
			else _editor = editor;
			_editor.Hide();
			if(!_treelistview.Controls.Contains(_editor))
				_treelistview.Controls.Add(_editor);
			_editorhandle = new TreeListViewItemEditControlHandle(_treelistview, _editor);
			AssignHandle(handle);
		}
		#endregion

		#region Functions
		public void ShowEditControl()
		{
			if(_treelistview.FocusedItem == null) return;
			ListViewItem item = (ListViewItem) _treelistview.EditedItem.Item;
			Rectangle rec = _treelistview.EditedItem.ColumnIndex > 0 ?
				_treelistview.GetSubItemRect(item.Index, _treelistview.EditedItem.ColumnIndex) :
				_treelistview.GetItemRect(item.Index, ItemBoundsPortion.Label);
			_editor.Size = rec.Size;
			_editor.Location = rec.Location;
			_editor.Top--;
			_editor.Show();
			_editor.Text = item.SubItems[_treelistview.EditedItem.ColumnIndex].Text;
			_editor.Focus();
		}
		public void HideEditControl()
		{
			_editor.Hide();
			ReleaseHandle();
			_editorhandle.ReleaseHandle();
		}
		#endregion

		#region WndProc
		public void SendMessage(ref Message m)
		{
			WndProc(ref m);
		}
		protected override void WndProc(ref Message m)
		{
			switch(m.Msg)
			{
				case (int)APIsEnums.WindowMessages.SHOWWINDOW:
					bool show = m.WParam != IntPtr.Zero;
					if(show) ShowEditControl();
					else HideEditControl();
					return;
			}
		}
		#endregion
	}
	internal class TreeListViewItemEditControlHandle : NativeWindow, IWin32Window
	{
		#region Properties
		private Control _control;
		private TreeListView _treelistview;
		new public IntPtr Handle
		{
			get{return base.Handle;}
		}
		#endregion
		#region Constructor / Destructor
		public TreeListViewItemEditControlHandle(TreeListView treelistview, Control control)
		{
			_control = control;
			_treelistview = treelistview;
			if(!control.Created) control.CreateControl();
			AssignHandle(control.Handle);
		}
		#endregion

		#region End edit
		private void EndEdit(bool Cancel)
		{
			IntPtr lparam = IntPtr.Zero;
			if(Cancel == false)
				lparam = Marshal.StringToCoTaskMemAuto(_control.Text);
			APIsUser32.SendMessage(
				_treelistview.Handle,
				(int) APIsEnums.ListViewMessages.CANCELEDITLABEL,
				IntPtr.Zero,
				lparam);
		}
		#endregion
		#region OnKillFocus
		private bool OnKillFocus(Message m)
		{
			// If the control is a combobox don't end edit if the handle is a handle
			// of one of the sub controls of the combobox
			if(_control.GetType() != typeof(ComboBox) && !_control.GetType().IsSubclassOf(typeof(ComboBox))) return true;
			APIsStructs.PCOMBOBOXINFO info = new APIsStructs.PCOMBOBOXINFO();
			info.cbSize = (uint)Marshal.SizeOf(typeof(APIsStructs.PCOMBOBOXINFO));
			if(!APIsUser32.GetComboBoxInfo(_control.Handle, ref info)) return true;
			if(m.WParam == info.hwndCombo || m.WParam == info.hwndItem || m.WParam == info.hwndList)
			{
				ReleaseHandle();
				AssignHandle(m.WParam);
				return false;
			}
			return true;
		}
		#endregion
		#region Wndproc
		protected override void WndProc(ref Message m)
		{
			switch(m.Msg)
			{
				case (int) APIsEnums.WindowMessages.KEYDOWN:
					Keys key = (Keys)(int) m.WParam;
					if(key != Keys.Return && key != Keys.Escape) break;
					bool Cancel = key != Keys.Enter;
					EndEdit(Cancel);
					break;
				case (int) APIsEnums.WindowMessages.KILLFOCUS:
					if(OnKillFocus(m))
					{
						EndEdit(true);
						return;
					}
					break;
			}
			base.WndProc(ref m);
		}
		private int HighOrder(IntPtr Param)
		{
			int intparam = Param.ToInt32();
			return (intparam >> 16) & 0x0000ffff;
		}
		private int LowOrder(IntPtr Param)
		{
			int intparam = Param.ToInt32();
			return intparam & 0x0000ffff;
		}
		#endregion
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)


Written By
Web Developer
France France
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions