Color Picker

Verschiedene Controls zum Auswählen von Farben

Controls zum Auswählen und Anzeigen von Farben braucht man oft. Der Windows ColorDialog bietet mir zu wenig Komfort, außerdem bin ich immer noch nicht hinter die Logik gestiegen, mit der bevorzugte Farben festgelegt werden können.

Hier wäre mal eine Auswahl geeigneter Controls.

Als kleines Extra hab ich einen Gradient Picker dazu gepackt.

Ein ColorPicker sollte meiner Meinung nach folgende Eigenschaften haben:

  • Color: Die Farbe, die angezeigt wird oder ausgewählt wurde
  • Event ColorChanged: Ein Event, das darüber informiert, dass eine neue Farbe ausgewählt wurde.

Also bräuchte man eigentlich nur ein Interface:

Public Interface IColorControl
Property Color()As Color
Event ColorChanged (ByVal Sender As IColorControl)
End Interface

Dieses Interface liefert die Funktionalität, die ich für einen ColorPicker brauche. Die Eigenschaft Color liefert die aktuell am Control eingestellte Farbe oder legt diese fest. Ein ColorChanged-Event braucht nur geliefert zu werden, wenn ich die Color-Eigenschaft von intern (also durch Bedienung des Controls selber) ändere. Wenn ich die Color-Eigenschaft im Code für das Control festlege, brauche ich kein Event.

Dieses Interface implementieren alle enthaltenen Controls zur einfachen Farbauswahl.

Im einzelnen wären dies:

BiColorBox

Zeigt einen Start- und aktuellen Farb-Wert an und kann gegebenenfalls den aktuellen auf den Start-Wert zurück setzen.

ColorCollectorPanel

Ein Control, mit dem man bevorzugte Farben anzeigen und auswählen kann. Man kann selbst Farben hinzufügen oder entfernen oder mit der Maus neu sortieren.

ColorWheelPanel

Bietet für eine Start-Farbe dazu passende Farben aus dem Farbkreis zur Auswahl an.

EyeDropperButton

Auswählen der Farbe eines Pixels auf dem Bildschirm mit einer Pipette.

CMYKControl

Ein Control, mit dem man einen CMYK-Farb-Wert anzeigen oder festlegen kann.

HexColorControl

Ein Control, mit dem man einen Hexadezimal-Farb-Wert anzeigen oder festlegen kann.

HSBControl

Ein Control, mit dem man einen HSB-Farb-Wert anzeigen oder festlegen kann.

Adobe ColorPicker Clone

Dem Adobe-Farbwähler nachgebildetes Control zum Anzeigen und Festlegen von Farben.

Daneben sind noch eine GradientColorBox zum Anzeigen von Farbgradienten und ein GradientStyleSelector zum Auswählen eines Farbverlaufs aus verschiedenen Varianten und DropDownButtons zum Anzeigen von Gradient- oder solitären Farben enthalten.

Wesentliche Anregung und Favorit für mich ist der Adobe Color Picker Clone von Daniel E. Blanchard auf codeproject.com. Dieses Control ist in C# geschrieben und lies für meine Zwecke ein paar Wünsche offen. Also habe ich das Projekt mal nach VB.NET übersetzt und nach eigenen Ansprüchen umgestaltet. Für die Verständlichkeit wichtig hielt ich, dass alle Farbeinstellungen nur durch Color-Strukturen vorgenommen werden. So kann man nun z.B. die HSB- und CMYK- oder HexColor-Boxen auch als separate Controls verwenden.

Um Farbwerte als Text anzugeben, brauchte ich TextBoxes, die nur bestimmte Tasten und Inhalte akzeptieren (auch nach Paste von Inhalten), sich also sozusagen selbst validieren. Dafür habe ich die Basisklasse ValidatedTextBox entworfen, die von der TextBox erbt und nach den Events TextChanged, Validating und KeyPress eine einfache Validierung (in den erbenden Klassen) verlangt.

Ein wenig Kopfzerbrechen hat mir die Pipetten-Funktion abverlangt. Sie sollte ohne API auskommen und nur .NET-Code enthalten. Als Lösung kam ich auf folgende Idee: Man legt einfach über den Screen eine fast vollständig transparente Windows Form und platziert diese mit der MousePosition als Mittelpunkt. Diese transparente Form wird der Maus überallhin nachgeführt. So ist gesichert, das die Maus überall auf dem Desktop ihr Pipetten-Symbol anzeigen kann. Die Function GetColor sieht so aus:

Private Function GetColor() As Color
Dim MP As Point = Control.MousePosition
Dim BMP As New Bitmap(1, 1, Drawing.Imaging.PixelFormat.Format32bppArgb)
Using g As Graphics = Graphics.FromImage(BMP)
g.CopyFromScreen(MP.X, MP.Y, 0, 0, New Size(1, 1), CopyPixelOperation.SourceCopy)
End Using
Return BMP.GetPixel(0, 0)
End Function

Bei jeder Änderung der Mausposition wird die Farbe unter der Maus neu bestimmt und wenn nötig ein Event geliefert, das zur Änderung der Vorschau-Farbe auf dem EyeDropperButton führt. Bei Linksklick auf die transparente Form oder nach Betätigen der Enter-Taste wird die transparente Form mit DialogResult.OK geschlossen. Falls die Form mit einem anderen DialogResult (andere Taste der Tastatur oder Maus) geschlossen wird, führt die zum Zurücksetzen der Farbe im EyeDropperButton zum ursprünglichen Wert.

Viel Spaß beim Ausprobieren.