Reputation: 1365
Is there a way to have the color dialog display on the form without the window border? To make things a bit more clearer, I want it sort of like the one used in the Paint program so that I'm able to change colors of lines drawn on a picturebox without having to open up the dialog again and again:
I'm placing it inside a vertical groupbox, and I want it to be able to fit in it. Can it be done?
Upvotes: 1
Views: 4896
Reputation: 106
You'll have to create your own palette.
Here's a usercontrol i wrote with comments. I've added a OnSelectionChanged event that will be fired when user changes color.
You can either use the designer to specify colors, events and other properties or you can hard-code them.
public partial class UserControl1 : UserControl
{
// The event raised when a user changes color
[Category("Behavior")]
public event EventHandler OnSelectionChanged;
/*
* Properties
*
*/
private Color[] m_Colors = new Color[] {}; // Colors on the palette
private Color m_SelectedColor; // Stores selected color
private int m_MaxColorsPerLine = 14; // Max colors per line
public Color[] Colors
{
get { return m_Colors; }
set { m_Colors = value; }
}
[Browsable(false)]
public Color SelectedColor
{
get { return m_SelectedColor; }
}
public int MaxColorsPerLine
{
get { return m_MaxColorsPerLine; }
set { m_MaxColorsPerLine = value; }
}
public UserControl1()
{
InitializeComponent();
}
private void UserControl1_Load(object sender, EventArgs e)
{
this.Controls.Clear();
int COLOR_WIDTH = 16;
int COLOR_HEIGHT = 16;
// Border colors
Color NEUTRAL_COLOR = Color.Black;
Color HIGHLIGHTED_COLOR = Color.Orange;
Color SELECTED_COLOR = Color.Red;
// Populate the palette
for(int i = 0; i < m_Colors.Length; ++i)
{
// Get where the current color should be positioned.
int linePos = (int)Math.Floor((double) i / m_MaxColorsPerLine);
int colPos = i % m_MaxColorsPerLine;
int posX = COLOR_WIDTH * colPos;
int posY = COLOR_HEIGHT * linePos;
// Create the panel that will hold the color
Panel pnl = new Panel();
pnl.Width = COLOR_WIDTH;
pnl.Height = COLOR_HEIGHT;
pnl.Location = new Point(posX, posY);
pnl.BackColor = m_Colors[i];
pnl.ForeColor = NEUTRAL_COLOR;
// Change border color when highlighted
pnl.MouseEnter += (s, args) => pnl.ForeColor = HIGHLIGHTED_COLOR;
// Change border color when mouse leaves
pnl.MouseLeave += (s, args) =>
{
if (pnl.Tag != null && (bool)pnl.Tag == true)
{
pnl.ForeColor = SELECTED_COLOR; // restore selected border color on mouse leave if selected
}
else
{
pnl.ForeColor = NEUTRAL_COLOR; // restore normal border color on mouse leave if not selected
}
};
// Change border color when selected
pnl.Click += (s, args) =>
{
if (pnl.Tag == null || (bool)pnl.Tag == false)
{
pnl.ForeColor = SELECTED_COLOR;
pnl.Tag = true; // Use the Tag member to store whether the color is selected
m_SelectedColor = pnl.BackColor;
// Raise the SelectionChanged event if this panel is not already selected
if (OnSelectionChanged != null)
{
OnSelectionChanged(this, EventArgs.Empty);
}
}
// Unselect other colors
foreach (Panel otherColor in this.Controls)
{
if (otherColor == pnl)
continue;
if (pnl.Tag != null && (bool)pnl.Tag == true)
{
otherColor.ForeColor = NEUTRAL_COLOR;
otherColor.Tag = false;
}
}
};
// Draw borders
pnl.Paint += (s, args) =>
{
Rectangle outterRect = args.ClipRectangle;
Rectangle innerRect = new Rectangle(outterRect.X + 1, outterRect.Y + 1, outterRect.Width - 3, outterRect.Height - 3);
// Draw outter rectangle
args.Graphics.DrawRectangle(
new Pen(
new SolidBrush(pnl.ForeColor), 2),
outterRect);
// Draw inner rectangle
args.Graphics.DrawRectangle(
new Pen(
Brushes.White, 1),
innerRect);
};
// Finally, add color panel to the control
this.Controls.Add(pnl);
}
}
}
Upvotes: 2
Reputation: 4262
You can easily build it yourself. Use a TableLayoutPanel
or FlowLayoutPanel
and a add a list of small PictureBox
with the background color set on the color you want. Then handle the Click
event to return/use their background color.
private void Form1_Load(object sender, EventArgs e)
{
pictureBox3.Click += HandleColorPick;
pictureBox4.Click += HandleColorPick;
pictureBox5.Click += HandleColorPick;
pictureBox6.Click += HandleColorPick;
pictureBox7.Click += HandleColorPick;
pictureBox8.Click += HandleColorPick;
pictureBox9.Click += HandleColorPick;
}
private void HandleColorPick(object sender, EventArgs e)
{
var s =(PictureBox) sender;
MessageBox.Show(s.BackColor.ToString());
}
Upvotes: 3
Reputation: 8104
Why not some 3rd party opensource control?
http://www.codeproject.com/Tips/638824/Yet-Another-Color-Picker-for-Csharp-VB-NET-WinForm or http://www.blackbeltcoder.com/Articles/controls/colorpicker-controls-for-winforms
Upvotes: 1