C# Windows Forms Autocomplete Rich Text ComboBox for TextBox (similar to Google)

Hello,
I'm looking for a way to do this in my Form application
as illustrated in the following picture.
The ComboBox Item can be Rtf or Html.
Note: No need to deal with the content of the ComboBox.
Thanks, Aryeh.
Picture of the desired Rich Text Combobox for TextBox
tuchfeldAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

tuchfeldAuthor Commented:
hmm... See Example:
ComboBox.DrawItem Event (msdn.microsoft)
Now I just need to know where to place the ComboBox when Key is Pressed.
0
tuchfeldAuthor Commented:
Better, use TextBox and ListBox and handle Events programmatically.
0
it_saigeDeveloperCommented:
Here is an autocomplete textbox implementation that uses methodology suggested by Eric Moreau - A more useful auto-complete Textbox control:

AutoCompleteTextBox.cs -
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace EE_Q28675001
{
	public partial class AutoCompleteTextBox : TextBox
	{
		public string[] Values { get; set; }
		public List<string> SelectedValues { get { return new List<string>((IEnumerable<string>)Text.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)); } }

		public AutoCompleteTextBox()
		{
			InitializeComponent();
			ResetListBox();
		}

		private void ShowListBox()
		{
			if (!IsAdded)
			{
				Parent.Controls.Add(ListBox);
				ListBox.Left = Left;
				ListBox.Top = Top + Height;
				ListBox.Width = Width;
				IsAdded = true;
			}

			ListBox.Visible = true;
			ListBox.BringToFront();
		}

		private void UpdateListBox()
		{
			if (Text.Equals(FormerValue))
				return;

			FormerValue = Text;
			string word = GetWord();

			if (Values != null && word.Length > 0)
			{
				string[] matches = Array.FindAll(Values, x => (x.StartsWith(word, StringComparison.OrdinalIgnoreCase) || x.Contains(word)) && !SelectedValues.Contains(x));
				if (matches.Length > 0)
				{
					ShowListBox();
					ListBox.Items.Clear();
					Array.ForEach(matches, x => ListBox.Items.Add(x));
					ListBox.SelectedIndex = 0;
					ListBox.Height = 0;
					ListBox.Width = 0;
					using (Graphics graphics = ListBox.CreateGraphics())
					{
						for (int i = 0; i < ListBox.Items.Count; i++)
						{
							ListBox.Height += ListBox.GetItemHeight(i);
							int width = Convert.ToInt32(graphics.MeasureString(string.Format("{0} ", ListBox.Items[i] as string), ListBox.Font).Width);
							ListBox.Width = ListBox.Width < width ? width : Width;
						}
					}
				}
				else
					ResetListBox();
			}
			else
				ResetListBox();
		}

		private string GetWord()
		{
			string _text = Text;
			int position = SelectionStart;

			int start = _text.LastIndexOf(' ', position < 1 ? 0 : position - 1);
			start = start == -1 ? 0 : start + 1;
			int end = _text.IndexOf(' ', position);
			end = end == -1 ? _text.Length : end;

			int length = end - start < 0 ? 0 : end - start;
			return _text.Substring(start, length);
		}

		private void InsertWord(string word)
		{
			string _text = Text;
			int position = SelectionStart;

			int start = _text.LastIndexOf(' ', position < 1 ? 0 : position - 1);
			start = start == -1 ? 0 : start + 1;
			int end = _text.IndexOf(' ', position);

			string part = string.Format("{0}{1}", _text.Substring(0, start), word);
			string updated = string.Format("{0}{1}", part, (end == -1) ? string.Empty : _text.Substring(end, _text.Length - end));

			Text = updated;
			SelectionStart = part.Length;
		}

		private void ResetListBox()
		{
			ListBox.Visible = false;
		}

		private void OnKeyDown(object sender, KeyEventArgs e)
		{
			switch (e.KeyCode)
			{
				case Keys.Down:
					if (ListBox.Visible && ListBox.SelectedIndex < ListBox.Items.Count - 1)
						ListBox.SelectedIndex++;
					break;
				case Keys.Tab:
					if (ListBox.Visible)
					{
						InsertWord(ListBox.SelectedItem as string);
						ResetListBox();
						FormerValue = Text;
					}
					break;
				case Keys.Up:
					if (ListBox.Visible && ListBox.SelectedIndex > 0)
						ListBox.SelectedIndex--;
					break;
				default:
					break;
			}
		}

		private void OnKeyUp(object sender, KeyEventArgs e)
		{
			UpdateListBox();
		}

		protected override bool IsInputKey(Keys keyData)
		{
			switch (keyData)
			{
				case Keys.Tab:
					return true;
				default:
					return base.IsInputKey(keyData);
			}
		}
	}
}

Open in new window

AutoCompleteTextBox.Designer.cs -
namespace EE_Q28675001
{
	partial class AutoCompleteTextBox
	{
		/// <summary> 
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.IContainer components = null;

		/// <summary> 
		/// Clean up any resources being used.
		/// </summary>
		/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
		protected override void Dispose(bool disposing)
		{
			if (disposing && (components != null))
			{
				components.Dispose();
			}
			base.Dispose(disposing);
		}

		#region Component Designer generated code

		/// <summary> 
		/// Required method for Designer support - do not modify 
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.ListBox = new System.Windows.Forms.ListBox();
			this.SuspendLayout();
			// 
			// ListBox
			// 
			this.ListBox.Location = new System.Drawing.Point(0, 0);
			this.ListBox.Name = "ListBox";
			this.ListBox.Size = new System.Drawing.Size(120, 96);
			this.ListBox.TabIndex = 0;
			// 
			// AutoCompleteTextBox
			// 
			this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.OnKeyDown);
			this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.OnKeyUp);
			this.ResumeLayout(false);

		}

		#endregion

		private System.Windows.Forms.ListBox ListBox;
		private bool IsAdded;
		private string FormerValue = string.Empty;
	}
}

Open in new window

Example usage:
Form1.cs -
using System;
using System.Windows.Forms;

namespace EE_Q28675001
{
	public partial class Form1 : Form
	{
		public Form1()
		{
			InitializeComponent();
		}

		private void OnLoad(object sender, EventArgs e)
		{
			autoCompleteTextBox1.Values = new string[] { "television espanola", "television argentina", "television band", "television without pity", "telephone espanola", "telephone argentina", "telephone band", "telephone without pity" };
		}
	}
}

Open in new window

Form1.Designer.cs -
namespace EE_Q28675001
{
	partial class Form1
	{
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.IContainer components = null;

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
		protected override void Dispose(bool disposing)
		{
			if (disposing && (components != null))
			{
				components.Dispose();
			}
			base.Dispose(disposing);
		}

		#region Windows Form Designer generated code

		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.autoCompleteTextBox1 = new EE_Q28675001.AutoCompleteTextBox();
			this.SuspendLayout();
			// 
			// autoCompleteTextBox1
			// 
			this.autoCompleteTextBox1.Location = new System.Drawing.Point(12, 13);
			this.autoCompleteTextBox1.Name = "autoCompleteTextBox1";
			this.autoCompleteTextBox1.Size = new System.Drawing.Size(260, 20);
			this.autoCompleteTextBox1.TabIndex = 0;
			this.autoCompleteTextBox1.Values = null;
			// 
			// Form1
			// 
			this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
			this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
			this.ClientSize = new System.Drawing.Size(284, 262);
			this.Controls.Add(this.autoCompleteTextBox1);
			this.Name = "Form1";
			this.Text = "Form1";
			this.Load += new System.EventHandler(this.OnLoad);
			this.ResumeLayout(false);
			this.PerformLayout();

		}

		#endregion

		private AutoCompleteTextBox autoCompleteTextBox1;
	}
}

Open in new window

Produces the following output -Capture.JPG-saige-
0
Cloud Class® Course: Python 3 Fundamentals

This course will teach participants about installing and configuring Python, syntax, importing, statements, types, strings, booleans, files, lists, tuples, comprehensions, functions, and classes.

Éric MoreauSenior .Net ConsultantCommented:
saige, that doesn't answer tuchfeld question! he wants to highlight the portion of text that does not match the inputted value!
0
it_saigeDeveloperCommented:
I assumed that his statement:
Note: No need to deal with the content of the ComboBox.
Meant that he did not care about highlighting the unmatched portion of the text.

-saige-
0
tuchfeldAuthor Commented:
Éric Moreau is right - As I wrote I need a Formatted items of the ListBox.
Anyway I already found a Solution:
autoCompleteListBox.DrawItem += new DrawItemEventHandler(autoCompleteListBox_DrawItem);
void autoCompleteListBox_DrawItem(object sender, DrawItemEventArgs e)
{
    // ...
    Image img = html_to_image(html, e.Bounds.Width);
    Point tp = new Point(0, e.Bounds.Y);
    g.DrawImage(img, tp);
    //...
}
private Image html_to_image(string html, int width)
{
    WebBrowser wb = new WebBrowser();
    wb.Width = width;
    wb.ScrollBarsEnabled = false;
    wb.DocumentCompleted += webBrowser_DocumentCompleted;
    wb.DocumentText = html;
    while (wb.ReadyState != WebBrowserReadyState.Complete) { Application.DoEvents(); }
    Bitmap bitmap = new Bitmap(wb.Width, 15);
    wb.DrawToBitmap(bitmap, new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height));
    return bitmap;
}

Open in new window

p.s. eventually, I didn't use HTML Renderer because of lack in RTL support... It is a bit slow to use WebBrowser for rendering.. but tolerable.
0
it_saigeDeveloperCommented:
My mistake, I misunderstood your requirements.  After borrowing some code from cjbarth's implementation of an Advanced ListBox (I was more interested in the highlighting functionality).  I came up with this implementation.  Let me know if this is what you are after:

AutoCompleteTextBox.cs -
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace EE_Q28675001
{
	public partial class AutoCompleteTextBox : TextBox
	{
		public string[] Values { get; set; }
		public List<string> SelectedValues { get { return new List<string>((IEnumerable<string>)Text.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)); } }

		public AutoCompleteTextBox()
		{
			InitializeComponent();
			ListBox.DrawMode = DrawMode.OwnerDrawFixed;
			ResetListBox();
		}

		private void ShowListBox()
		{
			if (!IsAdded)
			{
				Parent.Controls.Add(ListBox);
				ListBox.Left = Left;
				ListBox.Top = Top + Height;
				ListBox.Width = Width;
				IsAdded = true;
			}

			ListBox.Visible = true;
			ListBox.BringToFront();
		}

		private void UpdateListBox()
		{
			if (Text.Equals(FormerValue))
				return;

			FormerValue = Text;
			string word = GetWord();

			if (Values != null && word.Length > 0)
			{
				string[] matches = Array.FindAll(Values, x => x.StartsWith(word, StringComparison.OrdinalIgnoreCase) && !SelectedValues.Contains(x));
				if (matches.Length > 0)
				{
					ShowListBox();
					ListBox.Items.Clear();
					Array.ForEach(matches, x => ListBox.Items.Add(x));
					ListBox.Height = 0;
					ListBox.Width = 0;
					using (Graphics graphics = ListBox.CreateGraphics())
					{
						for (int i = 0; i < ListBox.Items.Count; i++)
						{
							ListBox.Height += ListBox.GetItemHeight(i);
							int width = Convert.ToInt32(graphics.MeasureString(ListBox.Items[i] as string, ListBox.Font).Width);
							ListBox.Width = ListBox.Width < width ? width : Width;
						}
					}
				}
				else
					ResetListBox();
			}
			else
				ResetListBox();
		}

		private string GetWord()
		{
			string _text = Text;
			int position = SelectionStart;

			int start = _text.LastIndexOf(' ', position < 1 ? 0 : position - 1);
			start = start == -1 ? 0 : start + 1;
			int end = _text.IndexOf(' ', position);
			end = end == -1 ? _text.Length : end;

			int length = end - start < 0 ? 0 : end - start;
			return _text.Substring(start, length);
		}

		private void InsertWord(string word)
		{
			string _text = Text;
			int position = SelectionStart;

			int start = _text.LastIndexOf(' ', position < 1 ? 0 : position - 1);
			start = start == -1 ? 0 : start + 1;
			int end = _text.IndexOf(' ', position);

			string part = string.Format("{0}{1}", _text.Substring(0, start), word);
			string updated = string.Format("{0}{1}", part, (end == -1) ? string.Empty : _text.Substring(end, _text.Length - end));

			Text = updated;
			SelectionStart = part.Length;
		}

		private void ResetListBox()
		{
			ListBox.Visible = false;
		}

		private void OnKeyDown(object sender, KeyEventArgs e)
		{
			switch (e.KeyCode)
			{
				case Keys.Down:
					if (ListBox.Visible && ListBox.SelectedIndex < ListBox.Items.Count - 1)
						ListBox.SelectedIndex++;
					break;
				case Keys.Tab:
					if (ListBox.Visible)
					{
						InsertWord(ListBox.SelectedItem as string);
						ResetListBox();
						FormerValue = Text;
					}
					break;
				case Keys.Up:
					if (ListBox.Visible && ListBox.SelectedIndex > 0)
						ListBox.SelectedIndex--;
					break;
				default:
					break;
			}
		}

		private void OnKeyUp(object sender, KeyEventArgs e)
		{
			UpdateListBox();
		}

		protected override bool IsInputKey(Keys keyData)
		{
			switch (keyData)
			{
				case Keys.Tab:
					return true;
				default:
					return base.IsInputKey(keyData);
			}
		}

		private void OnDrawItem(object sender, DrawItemEventArgs e)
		{
			// Draw the background of the ListBox control for each item.
			e.DrawBackground();

			//http://msdn.microsoft.com/en-us/library/6xe5hazb(VS.80).aspx
			e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
			e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
			e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;

			// Define the default color of the brush as black.
			Brush myBrush = Brushes.Black;
			Font regular = new Font(e.Font.FontFamily, e.Font.SizeInPoints, FontStyle.Regular);
			Font bold = new Font(e.Font.FontFamily, e.Font.SizeInPoints, FontStyle.Bold);

			List<TextSegment> phrases = ListBox.Items[e.Index].ToString().ToPhrases(new List<string>() { Text }).ToList(); // GetPhrases(ListBox.Items[e.Index].ToString()).ToList();

			Rectangle myBounds = e.Bounds;
			for (int i = 0; i <= phrases.Count - 1; i++)
			{
				TextSegment currentPhrase = default(TextSegment);
				TextSegment nextPhrase = default(TextSegment);
				Font workingFont = default(Font);
				bool lastPhrase = (i == phrases.Count);

				currentPhrase = phrases[i];

				if (i < phrases.Count - 1)
					nextPhrase = phrases[i + 1];

				if (currentPhrase.IsBold)
					workingFont = bold;
				else
					workingFont = regular;

				if (currentPhrase.Text.Length > 0)
				{
					e.Graphics.DrawString(currentPhrase.Text, workingFont, myBrush, myBounds, StringFormat.GenericDefault);
					if (!lastPhrase)
					{
						int textWidth = 0;
						if (currentPhrase.Width == 0)
						{
							textWidth = MeasureDisplayStringWidth(currentPhrase, workingFont, myBrush, myBounds);
							currentPhrase.Width = textWidth;
						}
						else
							textWidth = currentPhrase.Width;

						if (currentPhrase.Text[currentPhrase.Text.Length - 1] == ' ')
						{
							//we have to append a space
							SizeF spaceSize = e.Graphics.MeasureString(" ", regular);
							textWidth += Convert.ToInt32(spaceSize.Width);
						}
						myBounds.X = textWidth;
					}
				}
			}

			// If the ListBox has focus, draw a focus rectangle around the selected item.
			e.DrawFocusRectangle();
			//to fix a broken DrawFocusRectangle (I don't know why it sometimes doesn't work)
			if ((e.State & DrawItemState.Focus) == DrawItemState.Focus)
			{
				//the special rectangle size is to fix ghosting of the FocusRectangle
				ControlPaint.DrawFocusRectangle(e.Graphics, new Rectangle(e.Bounds.X, e.Bounds.Y + 1, e.Bounds.Width, e.Bounds.Height - 1));
			}
		}

		//http://www.bobpowell.net/lockingbits.htm
		private int MeasureDisplayStringWidth(TextSegment phrase, Font workingFont, Brush myBrush, Rectangle myBounds)
		{
			Rectangle myNewBounds = new Rectangle(myBounds.X, 0, myBounds.Width, myBounds.Height);
			using (Bitmap myBitmap = new Bitmap(Screen.AllScreens.Sum((Screen x) => x.WorkingArea.Width), myBounds.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb))
			{
				using (Graphics myGraphic = Graphics.FromImage(myBitmap))
				{
					myGraphic.SmoothingMode = SmoothingMode.HighQuality;
					myGraphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
					myGraphic.PixelOffsetMode = PixelOffsetMode.HighQuality;

					myGraphic.DrawString(phrase.Text, workingFont, myBrush, myNewBounds, StringFormat.GenericDefault);
					myGraphic.Flush();
				}

				System.Drawing.Imaging.BitmapData bitmapData = myBitmap.LockBits(new Rectangle(0, 0, myBitmap.Width, myBitmap.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, myBitmap.PixelFormat);

				int size = Math.Abs(bitmapData.Stride) * bitmapData.Height;
				byte[] data = new byte[size];

				Marshal.Copy(bitmapData.Scan0, data, 0, size);

				byte[][] pixelArray = new byte[myBitmap.Height + 1][];

				//we have to load all the opacity pixels into an array for later scanning by column
				//the data comes in rows
				for (int y = myBitmap.Height - 1; y >= 0; y += -1)
				{
					byte[] rowArray = new byte[bitmapData.Stride + 1];
					Array.Copy(data, y * bitmapData.Stride, rowArray, 0, bitmapData.Stride);
					//For x = myBitmap.Width - 1 To 0 Step -1
					//	Dim i = (y * bitmapData.Stride) + (x * 4)
					//	Dim B = data(i)
					//	Dim G = data(i + 1)
					//	Dim R = data(i + 2)
					//	Dim A = data(i + 3)
					//Next
					pixelArray[y] = rowArray;
				}

				//scan by column for the last pixel containing data
				for (int x = bitmapData.Stride - 1; x >= 0; x += -1)
				{
					for (int y = myBitmap.Height - 1; y >= 0; y += -1)
					{
						//that is, it contains data
						if (pixelArray[y][x] > 0)
						{
							//divide by 4, because there are 4 bytes per pixel
							//floor makes sure we always return the current pixel instead of jumping to the next pixel by rounding up
							return Convert.ToInt32(Math.Floor(x / 4m));
						}
					}
				}
			}
			return 0;
		}
	}
}

Open in new window


AutoCompleteTextBox.Designer.cs -
namespace EE_Q28675001
{
	partial class AutoCompleteTextBox
	{
		/// <summary> 
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.IContainer components = null;

		/// <summary> 
		/// Clean up any resources being used.
		/// </summary>
		/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
		protected override void Dispose(bool disposing)
		{
			if (disposing && (components != null))
			{
				components.Dispose();
			}
			base.Dispose(disposing);
		}

		#region Component Designer generated code

		/// <summary> 
		/// Required method for Designer support - do not modify 
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.ListBox = new System.Windows.Forms.ListBox();
			this.SuspendLayout();
			// 
			// ListBox
			// 
			this.ListBox.Location = new System.Drawing.Point(0, 0);
			this.ListBox.Name = "ListBox";
			this.ListBox.Size = new System.Drawing.Size(120, 96);
			this.ListBox.TabIndex = 0;
			this.ListBox.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.OnDrawItem);
			// 
			// AutoCompleteTextBox
			// 
			this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.OnKeyDown);
			this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.OnKeyUp);
			this.ResumeLayout(false);

		}

		#endregion

		private System.Windows.Forms.ListBox ListBox;
		private bool IsAdded;
		private string FormerValue = string.Empty;
	}
}

Open in new window


Support.cs -
using System.Collections.Generic;
using System.Linq;

namespace EE_Q28675001
{
	static class Extensions
	{
		public static bool IsNullOrWhiteSpace(this string source)
		{
			return string.IsNullOrEmpty(source) || source.Trim().Length == 0;
		}

		public static IEnumerable<TextSegment> ToPhrases(this string source, IEnumerable<string> filters)
		{
			return SplitString(source, filters);
		}

		public static IEnumerable<TextSegment> SplitString(this string source, IEnumerable<string> filters)
		{
			List<TextSegment> results = new List<TextSegment>();

			if (source.Length > 0)
			{
				results.Add(new TextSegment(source, true));

				if (filters != default(IEnumerable<string>))
				{
					foreach (string filter in filters)
					{
						int i = 0;
						while (i < results.Count)
						{
							string working = results[i].Text;
							string lowerInvariant = filter.ToLowerInvariant();
							string lower = working.ToLowerInvariant();
							if (lower.Contains(lowerInvariant) && results[i].IsBold)
							{
								if (lower.Equals(lowerInvariant))
									return results;

								string part1 = working.Substring(0, lower.IndexOf(lowerInvariant));
								string part2 = working.Substring(lower.IndexOf(lowerInvariant), lowerInvariant.Length);
								string part3 = working.Substring(lower.IndexOf(lowerInvariant) + lowerInvariant.Length, lower.Length - lower.IndexOf(lowerInvariant) - lowerInvariant.Length);

								if (part3.Length > 0 && part3[0] == ' ')
								{
									part2 += " ";
									part3 = part3.Trim();
								}

								results.RemoveAt(i);
								results.Insert(i, new TextSegment(part3, true));
								results.Insert(i, new TextSegment(part2, false));
								results.Insert(i, new TextSegment(part1, true));
							}
							i++;
						}
					}
				}
			}

			return results.Where(x => x.Text.Length > 0);
		}
	}

	public class TextSegment
	{
		public string Text { get; set; }
		public bool IsBold { get; set; }
		public int Width { get; set; }

		public TextSegment(string Text, bool IsBold)
		{
			this.Text = Text;
			this.IsBold = IsBold;
		}
	}
}

Open in new window


Implementation:

Form1.cs -
using System;
using System.Windows.Forms;

namespace EE_Q28675001
{
	public partial class Form1 : Form
	{
		public Form1()
		{
			InitializeComponent();
		}

		private void OnLoad(object sender, EventArgs e)
		{
			autoCompleteTextBox1.Values = new string[] { "television espanola", "television argentina", "television band", "television without pity", "espanola telephone", "argentina telephone", "band telephone", "without pity telephone" };
		}
	}
}

Open in new window


Form1.Designer.cs -
namespace EE_Q28675001
{
	partial class Form1
	{
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.IContainer components = null;

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
		protected override void Dispose(bool disposing)
		{
			if (disposing && (components != null))
			{
				components.Dispose();
			}
			base.Dispose(disposing);
		}

		#region Windows Form Designer generated code

		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.autoCompleteTextBox1 = new EE_Q28675001.AutoCompleteTextBox();
			this.SuspendLayout();
			// 
			// autoCompleteTextBox1
			// 
			this.autoCompleteTextBox1.Location = new System.Drawing.Point(12, 13);
			this.autoCompleteTextBox1.Name = "autoCompleteTextBox1";
			this.autoCompleteTextBox1.Size = new System.Drawing.Size(260, 20);
			this.autoCompleteTextBox1.TabIndex = 0;
			this.autoCompleteTextBox1.Values = null;
			// 
			// Form1
			// 
			this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
			this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
			this.ClientSize = new System.Drawing.Size(284, 262);
			this.Controls.Add(this.autoCompleteTextBox1);
			this.Name = "Form1";
			this.Text = "Form1";
			this.Load += new System.EventHandler(this.OnLoad);
			this.ResumeLayout(false);
			this.PerformLayout();

		}

		#endregion

		private AutoCompleteTextBox autoCompleteTextBox1;
	}
}

Open in new window


Produces the following output:Capture.JPG
-saige-
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
it_saigeDeveloperCommented:
Better screen shot based upon my prior post (partial selection of television):Capture.JPG
-saige-
0
tuchfeldAuthor Commented:
The snapshot and the input looks just what wanted.
I need to take a closer look at the code implementation (how is the graphics implemented).
0
it_saigeDeveloperCommented:
The graphics are handled in the OnDrawItem event and the strings are measured by the MeasureDisplayStringWidth method.

-saige-
0
tuchfeldAuthor Commented:
Thanks it_saige.. please keep in touch :-)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
.NET Programming

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.