The Control Customization sample demonstrates how to customize the Windows Forms controls.

In this sample, there're 4 examples:

1.       Multiple Column ComboBox.

2.       ListBox Items With Different ToolTips.

3.       Numeric-only TextBox.

4.       A Round Button.

Running the Sample

1. Multiple Column ComboBox.

   Demonstrates how to display multiple columns of data in the dropdown of a ComboBox

2. ListBox Items With Different ToolTips.

   Demonstrates how to display different tooltips on each items of the ListBox

3. Numeric-only TextBox.

   Demonstrates how to make a TextBox only accepts numbers

4. A Round Button.

   Demonstrates how to create a Button with irregular shape

Using the code

1. Example 1: "Multiple Column ComboBox".

   1). Create a DataTable with several columns and rows of data;

   2). Data bind the ComboBox control to the DataTable;

   3). Enable the owner draw on ComboBox by setting the DrawMode property to DrawMode.OwnerDrawFixed;

   4). Handle the DrawItem event on the ComboBox;

   5). In the DrawItem event handler, compute the bounds for each column and draw corresponding value for each column on its bounds.

             //  DataSource setup:
           //  Create a Table named Test and add 2 columns
           //   ID:     int
           //   Name:   string
           DataTable dtTest = new DataTable();
           dtTest.Columns.Add("ID", typeof(int));
           dtTest.Columns.Add("Name", typeof(string));

           dtTest.Rows.Add(1, "John");
           dtTest.Rows.Add(2, "Amy");
           dtTest.Rows.Add(3, "Tony");
           dtTest.Rows.Add(4, "Bruce");
           dtTest.Rows.Add(5, "Allen");

           // Bind the ComboBox to the DataTable
           this.comboBox1.DataSource = dtTest;
           this.comboBox1.DisplayMember = "Name";
           this.comboBox1.ValueMember = "ID";

           // Enable the owner draw on the ComboBox.
           this.comboBox1.DrawMode = DrawMode.OwnerDrawFixed;
           // Handle the DrawItem event to draw the items.
           this.comboBox1.DrawItem += delegate(object cmb, DrawItemEventArgs args)
               // Draw the default background

               // The ComboBox is bound to a DataTable,
               // so the items are DataRowView objects.
               DataRowView drv = (DataRowView)this.comboBox1.Items[args.Index];

               // Retrieve the value of each column.
               string id = drv["id"].ToString();
               string name = drv["name"].ToString();

               // Get the bounds for the first column
               Rectangle r1 = args.Bounds;
               r1.Width /= 2;

               // Draw the text on the first column
               using (SolidBrush sb = new SolidBrush(args.ForeColor))
                   args.Graphics.DrawString(id, args.Font, sb, r1);

               // Draw a line to isolate the columns 
               using (Pen p = new Pen(Color.Black))
                   args.Graphics.DrawLine(p, r1.Right, 0, r1.Right, r1.Bottom);

               // Get the bounds for the second column
               Rectangle r2 = args.Bounds;
               r2.X = args.Bounds.Width/2;
               r2.Width /= 2;

               // Draw the text on the second column
               using (SolidBrush sb = new SolidBrush(args.ForeColor))
                   args.Graphics.DrawString(name, args.Font, sb, r2);


2. Example 2: "ListBox Items With Different ToolTips".

   1). Add some items to the ListBox control;

   2). Handle the MouseMove event on the ListBox control;

   3). Call the ListBox.IndexFromPoint method to retrieve the item index at where the mouse hovers;

   4). If the mouse is over the items, call ToolTip.SetToolTip method to display a tooltip for the individual item.  

           // Setup the ListBox items

           this.listBox1.MouseMove += delegate(object lst, MouseEventArgs args)
               // Retrieve the item index at where the mouse hovers
               int hoverIndex = this.listBox1.IndexFromPoint(args.Location);

               // If the mouse is over the items, display a tooltip
               if (hoverIndex >= 0 && hoverIndex < listBox1.Items.Count)
                   this.toolTip1.SetToolTip(listBox1, listBox1.Items[hoverIndex].ToString());


3. Example 3: "Numeric-only TextBox".

   The make a TextBox accepts only numbers, we can handle the TextBox.KeyPress event, in the event handler use char.IsNumber method to filter the input keys. 

           // Handle the TextBox.KeyPress event to filter the input characters.
           this.textBox1.KeyPress += delegate(object tb, KeyPressEventArgs args)
               if (!(char.IsNumber(args.KeyChar) || args.KeyChar == '\b'))
                   // If the input character is not number or Backspace key
                   // Then set the Handled property to true to indicate that 
                   // the KeyPress event is handled, so that the TextBox just 
                   // bypass the input character.
                   args.Handled = true;


4. Example 4: "A Round Button".

   The key point of creating a round button is changing its Region property.  

  public class RoundButton : Button
      protected override void OnPaint(PaintEventArgs pevent)
          // Change the region for the button so that when clicks outside the ellipse bounds,
          // the Click event won't fire.
          GraphicsPath path = new GraphicsPath();
          path.AddEllipse(0, 0, ClientSize.Width, ClientSize.Height);
          this.Region = new Region(path);



More Information

��         Windows Forms General FAQ.

��         Shaped Windows Forms and Controls in Visual Studio .NET

��         Round Button in C#