Home > Blockchain >  How to create a button in WindowsForm with text "ok" in it but split into 2 backcolors?
How to create a button in WindowsForm with text "ok" in it but split into 2 backcolors?

Time:12-10

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:

  1. how to fix the code below related to the timer idea?(aka how to put the button in the background?)
  2. 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;
    }
}
  • Related