Title: Make a persistent color palette in C#
This example saves and restores the colors in a color palette when it starts and stops. It also lets the user click on a color in the palette to change its value.
The program stores the colors in an array of Color. Several constants determine how big each color sample is and how many rows and columns of colors there are.
// The color palette.
Color[] Colors;
// The size used for each color patch.
const int PatchWidth = 16, PatchHeight = 16;
const int PatchMargin = 2;
const int NumRows = 6, NumCols = 8;
When the program starts, the form's Load event handler calls LoadColors to load the color palette.
// Load the colors.
private void LoadColors()
{
// See if we have saved colors.
if (Properties.Settings.Default.ColorValues.Length == 0)
{
// Use default colors.
Colors = DefaultColors();
}
else
{
// Use saved settings.
string[] argbs =
Properties.Settings.Default.ColorValues.Split(
new char[] { ',' },
StringSplitOptions.RemoveEmptyEntries);
List<Color> color_list = new List<Color>();
foreach (string argb in argbs)
{
color_list.Add(Color.FromArgb(int.Parse(argb)));
}
Colors = color_list.ToArray();
}
}
At design time, I opened Solution Explorer and double-clicked Properties. On the Settings tab shown in the picture below, I added a string property named ColorValues.
The LoadColors method checks the ColorValues setting to see if colors have been saved in a previous run. If there are no colors saved in that setting, the code calls the DefaultColors method to load some default colors. This method just creates an array filled with pre-defined colors. It isn't very interesting so it isn't shown here. Download the example to see for yourself.
If the ColorValues setting is non-blank, it contains a list of ARGB color values in integer format separated by commas. The code splits the string at the commas and uses the values to create new Color values, adding them to a List. It then sets the Colors array equal to the list's contents converted into an array.
When the form is closing, the following code saves the current color palette.
// Save the current colors.
private void Form1_FormClosing(object sender,
FormClosingEventArgs e)
{
SaveColors();
}
// Save the current colors.
private void SaveColors()
{
string argbs = "";
foreach (Color color in Colors)
{
argbs += color.ToArgb().ToString() + ",";
}
Properties.Settings.Default.ColorValues = argbs;
Properties.Settings.Default.Save();
}
The code loops through the colors in the Colors array, adding the integer ARGB representation of each to a string. It then saves the string in the ColorValues setting.
The two remaining pieces of code draw the color palette and let the user edit the colors. The example program displays the palette in a PictureBox. The following code shows how the PictureBox draws itself.
// Display the colors.
private void picPalette_Paint(object sender, PaintEventArgs e)
{
int max_x = PatchWidth * NumCols;
int x = 0, y = 0;
foreach (Color color in Colors)
{
using (SolidBrush br = new SolidBrush(color))
{
e.Graphics.FillRectangle(br, x, y,
PatchWidth, PatchHeight);
}
x += PatchWidth + PatchMargin;
if (x > max_x)
{
x = 0;
y += PatchHeight + PatchMargin;
}
}
}
The code uses the size of the color samples to calculate the width of a row and saves it as max_x. It then loops through the colors in the Colors array. For each color, it draws a sample of the color and increases the X coordinate where it will draw the next sample. If this moves beyond the end of the current row, the code sets the X coordinate to 0 and increases the Y coordinate for the next sample.
See the post Make a standard color palette in C# for another method of displaying a color palette.
The following code shows how the program lets the user edit colors.
// Let the user select a color.
private void picPalette_MouseClick(object sender, MouseEventArgs e)
{
// See which color was clicked.
int row = (int)(e.Y / (PatchHeight + PatchMargin));
int col = (int)(e.X / (PatchWidth + PatchMargin));
int index = row * NumCols + col;
// Let the user pick a color.
cdColor.Color = Colors[index];
if (cdColor.ShowDialog() == DialogResult.OK)
{
// The user clicked OK. Save the selected color.
Colors[index] = cdColor.Color;
picPalette.Refresh();
}
}
The PictureBox control's MouseClick event handler calculates the row and column that the user clicked. It sets the cdColor ColorDialog control's Color property to the corresponding color. (Note that the dialog will only select a color in its display if it happens to be one of the dialog's preset colors.) The code then displays the dialog. If the user selects a color and clicks OK, the code updates the color's entry in the Colors array and refreshes the PictureBox to show the new color.
Download the example to experiment with it and to see additional details.
|