I'm trying to extend the C# Button class so that I can color the button, with up to 3 colours, according to the percentages provided. It appears to work apart from the button text is not shown. Please can somebody advise how to display the text? Also, I'm unsure as to whether Refresh() is the correct method to call in the Setter methods to trigger a redraw with the new percentage provided? Many thanks.
class TriColorsButton : Button
{
private double percentOfLeftColor, percentOfRightColor;
public TriColorsButton(String text, double percentOfLeftColor, double percentOfRightColor)
{
this.Text = text;
this.percentOfLeftColor = percentOfLeftColor;
this.percentOfRightColor = percentOfRightColor;
}
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
Brush brush;
RectangleF rectFirst, rectSecond, rectThird;
Color c1, c2, c3;
// create the first rectangle
rectFirst = new RectangleF(0, 0, this.Width, this.Height);
// create the second rectangle
int callWidth = (int)(this.Width * (100 - percentOfRightColor) / 100);
rectSecond = new RectangleF(0, 0, callWidth, this.Height);
// create the third rectangle
int leftWidth = (int)(this.Width * percentOfLeftColor / 100);
rectThird = new RectangleF(0, 0, leftWidth, this.Height);
// create the colors
c1 = Constants.altFoldColor;
c2 = Constants.altCallColor;
c3 = Constants.altRaiseColor;
// create the brush
brush = new SolidBrush(c1);
// fill the segment
pe.Graphics.FillRectangle(brush, rectFirst);
// create the brush
brush = new SolidBrush(c2);
// fill the segment
pe.Graphics.FillRectangle(brush, rectSecond);
// create the brush
brush = new SolidBrush(c3);
// fill the segment
pe.Graphics.FillRectangle(brush, rectThird);
// dispose of the brush
brush.Dispose();
}
public void SetPercentOfLeftColor(double percentOfLeftColor)
{
this.percentOfLeftColor = percentOfLeftColor;
Refresh();
}
public double GetPercentOfLeftColor()
{
return percentOfLeftColor;
}
public void SetPercentOfRightColor(double percentOfRightColor)
{
this.percentOfRightColor = percentOfRightColor;
Refresh();
}
public double GetPercentOfRightColor()
{
return percentOfRightColor;
}
}
Also, although this paints the colors that I want, I lose the original look and feel of a standard button. I'd like to retain the standard button look and feel such as the on-hover highlighting and border of a standard button. How can I achieve this?
EDIT: Upon suggestion I tried to draw a background image for the button instead. This had a strange effect of causing most of my form to go white. It would redraw and look better if I moved the form on screen but other updates wouldn't happen appropriately. This is what I tried:
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
Image bmp = new Bitmap(Width, Height);
using (Graphics g = Graphics.FromImage(bmp))
{
Brush brush;
RectangleF rectFirst, rectSecond, rectThird;
Color c1, c2, c3;
// create the first rectangle
rectFirst = new RectangleF(0, 0, this.Width, this.Height);
// create the second rectangle
int callWidth = (int)(this.Width * (100 - percentOfRightColor) / 100);
rectSecond = new RectangleF(0, 0, callWidth, this.Height);
// create the third rectangle
int leftWidth = (int)(this.Width * percentOfLeftColor / 100);
rectThird = new RectangleF(0, 0, leftWidth, this.Height);
// create the colors
c1 = Constants.altFoldColor;
c2 = Constants.altCallColor;
c3 = Constants.altRaiseColor;
// create the brush
brush = new SolidBrush(c1);
// fill the segment
g.FillRectangle(brush, rectFirst);
// create the brush
brush = new SolidBrush(c2);
// fill the segment
g.FillRectangle(brush, rectSecond);
// create the brush
brush = new SolidBrush(c3);
// fill the segment
g.FillRectangle(brush, rectThird);
// dispose of the brush
brush.Dispose();
}
this.BackgroundImage = bmp;
}
EDIT2: I figured out how to achieve what I wanted. I added a method that draws and sets the background and called it from the constructor. The OnPaint method no longer requires an override:
private void SetBackgroundImage()
{
Image bmp = new Bitmap(Width, Height);
using (Graphics g = Graphics.FromImage(bmp))
{
Brush brush;
RectangleF rectFirst, rectSecond, rectThird;
Color c1, c2, c3;
// create the first rectangle
rectFirst = new RectangleF(0, 0, this.Width, this.Height);
// create the second rectangle
int callWidth = (int)(this.Width * (100 - percentOfRightColor) / 100);
rectSecond = new RectangleF(0, 0, callWidth, this.Height);
// create the third rectangle
int leftWidth = (int)(this.Width * percentOfLeftColor / 100);
rectThird = new RectangleF(0, 0, leftWidth, this.Height);
// create the colors
c1 = Constants.altFoldColor;
c2 = Constants.altCallColor;
c3 = Constants.altRaiseColor;
// create the brush
brush = new SolidBrush(c1);
// fill the segment
g.FillRectangle(brush, rectFirst);
// create the brush
brush = new SolidBrush(c2);
// fill the segment
g.FillRectangle(brush, rectSecond);
// create the brush
brush = new SolidBrush(c3);
// fill the segment
g.FillRectangle(brush, rectThird);
// dispose of the brush
brush.Dispose();
}
this.BackgroundImage = bmp;
}