Save a color palette in a program’s settings in C#


[color palette]

The example Make a persistent color palette in C# shows how a program can use settings to save and restore a color palette. The program saves the palette colors as a list of ARGB color values stored in a string and separated by commas.
actually
That method works but seems a bit unsatisfying. It would be nice if the settings could simply hold the color values instead of a string representing an array of values.

There are a couple of ways you can come closer to the ideal solution. First, you can build a custom type to wrap an array of Color and then make a type converter to save and restore values of that type. With some effort you can get that to work, but it’s complicated enough that I’d rather just stuck with the string representing the array.

A much better solution would be to make a setting that holds an array of Color. Unfortunately that’s not easy because settings must be serialized and deserialized as XML strings and Color isn’t serializable. (I have no idea why Microsoft didn’t make Color serializable. It would have been easy for them and would have been useful under many circumstances.)

One solution that actually works is to create a setting that holds an array of integers representing the color values’ ARGB values. This is slightly better than the single string containing all of the values separated by commas so this is the solution demonstrated by this example. You may also find other examples where you want to store an array of integers in a setting.

To get started, open Solution Explorer and double click the Properties entry. On the Settings tab, create a setting called Argbs and give it type int.

Unfortunately the settings tab won’t let you pick an array of int, but the settings system can actually handle such an array if you create it “by hand.” To do that, close the Properties window and expand its entry in Solution Explorer. Next right click the Settings.settings entry, select Open With, and pick one of the text editors such as XML Editor.

Find the setting’s definition inside the editor. It should look something like this:

<Setting Name="Argbs" Type="System.Int32" Scope="User">
  <Value Profile="(Default)">0</Value>
</Setting>

Simply change the setting’s type to System.Int32[] and change its default value to an empty value. The result should look like this:

<Setting Name="Argbs" Type="System.Int32[]" Scope="User">
  <Value Profile="(Default)" />
</Setting>

Now you can use the Args setting as an array in the program. The following code executes when the program starts.

// Load the colors.
private void LoadColors()
{
    if ((Properties.Settings.Default.Argbs == null) ||
        (Properties.Settings.Default.Argbs.Length == 0))
    {
        // Use default colors.
        Properties.Settings.Default.Argbs = DefaultColors();
    }
}

This code checks the setting to see if it is null or if the array is empty. In those cases, it sets the setting equal to the array returned by the DefaultColors method. (Download the example to see that method.)

The following code shows how the program draws the color palette represented by the setting.

// Display the colors.
private void picPalette_Paint(object sender, PaintEventArgs e)
{
    int max_x = PatchWidth * NumCols;
    int x = 0, y = 0;
    foreach (int argb in Properties.Settings.Default.Argbs)
    {
        Color color = Color.FromArgb(argb);
        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 loops through the setting array. For each integer value, it converts that value into a Color, uses the Color to create a brush, and then draws a sample of the brush.

The following code executes when the user clicks a color sample.

// 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 = Color.FromArgb(
        Properties.Settings.Default.Argbs[index]);
    if (cdColor.ShowDialog() == DialogResult.OK)
    {
        // The user clicked OK. Save the selected color.
        Properties.Settings.Default.Argbs[index] =
            cdColor.Color.ToArgb();
        picPalette.Refresh();
    }
}

This code figures out which color sample was clicked and displays a ColorDialog to let the user pick a new color. If the user picks a color and clicks OK, the code updates the corresponding entry in the setting array.

The following code executes when the form is closing.

// Save the current colors.
private void Form1_FormClosing(object sender,
    FormClosingEventArgs e)
{
    SaveColors();
}

// Save the current colors.
private void SaveColors()
{
    Properties.Settings.Default.Save();
}

The SaveColors method calls Properties.Settings.Default.Save to save the current setting values.

Download the example to see additional details.


Download Example   Follow me on Twitter   RSS feed   Donate




About RodStephens

Rod Stephens is a software consultant and author who has written more than 30 books and 250 magazine articles covering C#, Visual Basic, Visual Basic for Applications, Delphi, and Java.

This entry was posted in arrays, drawing, graphics, settings and tagged , , , , , , , , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *