I want to create a button,in WindowsForm using C#, with half of it filled with color red (backcolor) and the other half is in blue(backcolor),plus text "ok" centered.
I didn't know how to start, so i used a timer to fill ,as 10 ms pass,the colors.
But mind you the timer isn't what is asked,just a button split into 2 colors.
But the problem with the timer is that the graphics thing happens behind the button,but i need it to happen on the button,so like the button should be in the background not in the front.
So i shifted the timer filling above the button, so that you can see what i mean.
So:
- how to fix the code below related to the timer idea?(aka how to put the button in the background?)
- any alternative way?
This is what i've tried so far:
public Form1()
{
InitializeComponent();
}
Graphics g;
int y = 0; int x = 0;
private void Form1_Load(object sender, EventArgs e)
{
g = this.CreateGraphics();
}
private void button1_Click(object sender, EventArgs e)
{
timer1.Enabled = true;
}
private void timer1_Tick(object sender, EventArgs e)
{
this.Refresh();
g.FillRectangle(Brushes.Red, new Rectangle(new Point(button1.Location.X, button1.Location.Y-100), new Size(y,button1.Size.Height)));
if (y < (button1.Size.Width / 2))
y ;
else
{
g.FillRectangle(Brushes.Blue, new Rectangle(new Point(button1.Location.X button1.Size.Width/2, button1.Location.Y - 100), new Size(x, button1.Size.Height)));
if (x < (button1.Size.Width/2))
x ;
}
}
CodePudding user response:
This seems like a too complicated way to color a button. It's always a bad idea to overlay anything above a control. It can interfere with your clicks/events etc.
I would alternatively, use an image background with the two colors as described here
public Form1()
{
// Assign an image to the button.
button1.Image = Image.FromFile("C:\\Graphics\\MyBitmap.bmp");
// Align the image and text on the button.
button1.ImageAlign = ContentAlignment.MiddleRight;
button1.TextAlign = ContentAlignment.MiddleLeft;
// Give the button a flat appearance.
button1.FlatStyle = FlatStyle.Flat;
}
Unfortunately, there is not way to create a System.Drawing.Color
with gradient values to workaround your issue and assign to the background color propery of the button, so your best bet is an image background.
CodePudding user response:
Using a Bitmap as background is probably the simplest way.
You can build a Custom Control that generates a Bitmap, filled with the specified colors and assign it to the BackGroundImage
Property of a Button.
You can also add a public Property (here, an array named Colors
), that can be set at design-time or run-time, to change the color that fill the Bitmap
To use this Custom Control, add a class to the Project, name it ButtonBicolor
, replace everything with this code, build the Project, find the new Control in the ToolBox and drop it on a Form
Note: there's no custom editor attached to the Colors
property (or a designer), o you cannot set the single values in the PropertyGrid, you have to open up the dialog and confirm the change to see the new colors applied
using System.Drawing;
using System.Windows.Forms;
public class ButtonBicolor : Button {
private Color[] m_Colors = { Color.Red, Color.Blue };
private Bitmap background = null;
public ButtonBicolor() {
base.BackgroundImageLayout = ImageLayout.None;
BuildBackgroundImage();
}
protected override void OnResize(EventArgs e) {
base.OnResize(e);
BuildBackgroundImage();
}
public Color[] Colors {
get => m_Colors;
set {
m_Colors = value;
BuildBackgroundImage();
}
}
public new Image BackgroundImage => null;
public new ImageLayout BackgroundImageLayout => ImageLayout.None;
private void BuildBackgroundImage()
{
if (Colors is null || Colors.Length < 2) return;
background?.Dispose();
background = new Bitmap(ClientSize.Width, ClientSize.Height);
using (var g = Graphics.FromImage(background))
using (var brushLeft = new SolidBrush(Colors[0]))
using (var brushRight = new SolidBrush(Colors[1])) {
g.FillRectangle(brushLeft, new RectangleF(0, 0, background.Width / 2, background.Height));
g.FillRectangle(brushRight, new RectangleF(background.Width / 2, 0, background.Width / 2, background.Height));
}
base.BackgroundImage = background;
}
}