ColorComboBox

The Extended Color Set

The Basic Color Set

Introduction

This is a demonstration on the use of the ToolStripDropDown class by creating a color picker combobox. Honestly, I’m surprised that the .NET framework doesn’t come with this control, because any rich text editor application would need one of these in their toolbar.

Background

Because this is my first attempt at C# programming, my first thought for accomplishing the task of creating the ColorComboBox was to create a control that would inherit from a CheckBox, which, when checked, would create and display a form without a title bar, where the form would house the flat radio buttons representing the colors. While the popup window is being displayed, any mouse clicks outside of it have to be detected to close the popup. I soon learned that the only way to pick up the mouse click outside of the popup window is to use a Windows Hook (you all know that capturing the mouse would not allow the user to click on the child buttons). But, that would tie this control to Windows. So, I had to find a .NET way of doing the same thing; this led me to the ToolStripDropDown class.

The other problem with this thought process was that I was exposing the checkbox’s properties to the outside world. The checkbox needed to be flat, with no autosize, and the Text property had to be empty. The first two, if not set correctly, would have catastrophic results. So, I wrapped the entire thing with a UserControl-derived class to hide the CheckBox‘s properties from the user.

There was another hurdle to overcome. When the dropdown was being displayed and the user clicked on the dropdown button to dismiss the dropdown, it would close, and then immediately reopen. The only solution that I have found for this problem is to disable the dropdown button while the dropdown is being displayed. That is done with the help of a Timer. It is not the perfect solution, but it is the only one I could come up with.

So, the end result consists of a ColorComboBox (derived from UserControl) that contains a ColorComboButton (derived from CheckBox) that contains a PopupWindow (derived from ToolStripDropDown) that contains a ColorPopup (derived from UserControl) that contains a ColorRadioButton (derived from RadioButton).

Let me get into some detail.

Start with the ColorChangedHandler event. The ColorComboBox, PopupWindow, and ColorComboButton all have a ColorChangedHandler. The ones in PopupWindow and ColorComboButton are invisible to the class’ user; they are used internally to pass the color changed event down the chain of commands.

// define the color changed event argument
public class ColorChangeArgs : System.EventArgs
{
   public ColorChangeArgs(Color color)
   {
      this.color = color;
   }

   //the selected color
   public Color color;
}

// event handler delegate
public delegate void ColorChangedHandler(object sender,
                                         ColorChangeArgs e);

The ColorComboBox class, which inherits form UserControl, is pretty simple itself. It has a constructor and two event handlers, one for the SizeChanged event and another to catch the ColorChanged event form the color popup, to relay to the parent control.

public partial class ColorComboBox : UserControl
{
   /// <summary>
   /// Set or get the selected color
   /// </summary>>
   public Color SelectedColor
   {
      get
      {
         return button.SelectedColor;
      }
      set
      {
         button.SelectedColor = value;
      }
   }



   /// <summary>
   /// Set whether the control is in extended color mode or
   /// normal mode
   /// </summary>
   public Boolean Extended
   {
      set
      {
         button.Extended = value;
      }

      get
      {
         return button.Extended;
      }
   }

   /// <summary>
   /// color change event handler
   /// </summary>
   public event ColorChangedHandler ColorChanged;

   public ColorComboBox()
   {
      InitializeComponent();
      // set up event handler to catch the ColorChanged message
      // from the color popup
      button.ColorChanged +=
         new ColorChangedHandler(button_ColorChanged);
   }

   public void button_ColorChanged(object sender,
                                   ColorChangeArgs e)
   {
      if (ColorChanged != null)
      {
         ColorChanged(this, e);
      }
   }

   private void ColorComboBox_SizeChanged(object sender,
                                          EventArgs e)
   {
      button.Location = new Point(0, 0);
      button.Size = this.Size;
   }

}

More by Author

Must Read