【问题标题】:Set background color of button depending on percentage根据百分比设置按钮的背景颜色
【发布时间】:2021-05-04 11:17:04
【问题描述】:

在 c#, windows 窗体中,我想根据输入的双精度值更改按钮背景颜色,该值介于 1 和 100 之间。例如

  • 如果百分比为 100,则整个按钮颜色应为黄色。
  • 例如,如果75%,那么按钮的 75% 应该是黄色,25% 是蓝色,水平方向,这意味着 25% 按钮的左侧部分为蓝色,右侧部分为黄色。

【问题讨论】:

  • 我认为你没有理解这个问题。我希望部分按钮为一种颜色,部分按钮为另一种颜色,具体取决于输入值。如果输入值是例如20,我希望按钮的剩余 20% 为一种颜色,其余部分为另一种颜色。输入可以是 1 到 100 之间的任何数字。

标签: c# windows winforms button background-color


【解决方案1】:

您可以创建一个自定义按钮控件并使用它的 BackgroundImage 来绘制进度。这样你就可以保持按钮的外观和感觉(包括视觉风格)。所有的绘画逻辑都在控件中,应用代码如下:

private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
    percentButton1.Percent = (int)numericUpDown1.Value;
    percentButton1.Text = $"{ percentButton1.Percent}%";
}

这是你看到的结果:

在以下示例中,我为 PercentButton 创建了 3 个属性:

  • 百分比
  • PercentCompletedColor
  • 百分比剩余颜色

代码如下:

using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
public class PercentButton : Button
{
    public PercentButton()
    {
        BackgroundImageLayout = ImageLayout.Stretch;
    }

    Color percentCompletedColor = Color.Yellow;
    [DefaultValue(typeof(Color), "Yellow")]
    public Color PercentCompletedColor
    {
        get { return percentCompletedColor; }
        set
        {
            if (percentCompletedColor != value)
            {
                percentCompletedColor = value;
                Invalidate();
            }
        }
    }

    Color percentRemainingColor = Color.Blue;
    [DefaultValue(typeof(Color), "Blue")]
    public Color PercentRemainingColor
    {
        get { return percentRemainingColor; }
        set
        {
            if (percentRemainingColor != value)
            {
                percentCompletedColor = value;
                Invalidate();
            }
        }
    }

    private int percent = 50;
    [DefaultValue(50)]
    public int Percent
    {
        get { return percent; }
        set
        {
            if (value < 0) value = 0;
            if (value > 100) value = 100;
            if (percent != value)
            {
                percent = value;
                Invalidate();
            }
        }
    }

    [Browsable(false)]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
    public override Image BackgroundImage
    {
        get { return base.BackgroundImage; }
        set { base.BackgroundImage = value; }
    }

    [Browsable(false)]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
    public override ImageLayout BackgroundImageLayout
    {
        get { return base.BackgroundImageLayout; }
        set { base.BackgroundImageLayout = value; }
    }

    protected override void OnPaint(PaintEventArgs pevent)
    {
        if (BackgroundImage == null)
            BackgroundImage = new Bitmap(100, 10);
        using (var g = Graphics.FromImage(BackgroundImage))
        {
            if (Percent > 0)
                using (var b1 = new SolidBrush(PercentCompletedColor))
                    g.FillRectangle(b1, new Rectangle(0, 0, Percent, 10));
            if (Percent < 100)
                using (var b1 = new SolidBrush(PercentRemainingColor))
                    g.FillRectangle(b1, new Rectangle(Percent, 0, Percent, 10));
        }
        base.OnPaint(pevent);
    }
}

【讨论】:

  • 看起来不错。唯一的建议是通过检查value 是否等于已分配的值来防止对Invalidate 的不必要调用。比如set { if (value != percentRemainingColor) { percentRemainingColor = value; Invalidate(); } }等。这对于Percent属性来说可能是最重要的。正如所写,我可以一遍又一遍地为其分配相同的值,然后Invalidate 将被调用。
  • @Idle_Mind 背景图片是Stretch。(摆脱任何计算的最简单方法,同时保持按钮的外观和感觉。)
  • @Zer0,是的,我usually 关心它。
  • 拉伸...我完全错过了!
  • @Nenad Birešev 这能回答你的问题吗?如果您在应用答案时有任何问题,请告诉我:)
【解决方案2】:

您不能使用 BackgroundColor 属性同时拥有具有两种颜色的按钮。 首先,您必须创建一个组件按钮并自定义。 右键单击>添加新项目>从Windows窗体中选择CustomControl>输入名称>确定

之后,编辑代码就足够了。该类继承自按钮类而不是控件类

 public partial class TwoColorButton : Button
    {

        Color clr1, clr2;
        private Color color1 = Color.DodgerBlue;
        private Color color2 = Color.MidnightBlue;
        private int angle = 90;
        private int textX = 100;
        private int textY = 25;
        private String text = "";


        public int ButtonAngle
        {
            get { return angle; }
            set { angle = value; Invalidate(); }
        }
        public String ButtonText
        {
            get { return text; }
            set { text = value; Invalidate(); }
        }
        public Color StartColor
        {
            get { return color1; }
            set { color1 = value; Invalidate(); }
        }
        public Color EndColor
        {
            get { return color2; }
            set { color2 = value; Invalidate(); }
        }
        

        public int GradientAngle
        {
            get { return angle; }
            set { angle = value; Invalidate(); }
        }

        public int TextLocation_X
        {
            get { return textX; }
            set { textX = value; Invalidate(); }
        }
        public int TextLocation_Y
        {
            get { return textY; }
            set { textY = value; Invalidate(); }
        }      
        public TwoColorButton()
        {
            this.Size = new Size(100, 40);
            this.BackColor = Color.Transparent;
            this.FlatStyle = FlatStyle.Flat;
            this.FlatAppearance.BorderSize = 0;
            this.FlatAppearance.MouseOverBackColor = Color.Transparent;
            this.FlatAppearance.MouseDownBackColor = Color.Transparent;
            text = this.Text;
        }

       
        protected override void OnLostFocus(EventArgs e)
        {
            base.OnLostFocus(e);
            color1 = clr1;
            color2 = clr2;
            this.Invalidate();
        }

        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            textX = (int)((this.Width / 3) - 1);
            textY = (int)((this.Height / 3) + 5);
        }


        //draw circular button function  
       
        //draw rectangular button function  
        void DrawRectangularButton(Graphics g)
        {
            Color c1 = Color.FromArgb(250, color1);
            Color c2 = Color.FromArgb(250, color2);


            Brush b = new System.Drawing.Drawing2D.LinearGradientBrush(ClientRectangle, c1, c2, angle);
            g.FillRectangle(b, 0, 0, this.Width, this.Height);


            for (int i = 0; i < 2; i++)
            {
                g.DrawLine(new Pen(new SolidBrush(Color.FromArgb(220, 220, 220))), this.Width - i, 0, this.Width - i, this.Height);
                g.DrawLine(new Pen(new SolidBrush(Color.FromArgb(220, 220, 220))), 0, this.Height - i, this.Width, this.Height - i);

                g.DrawLine(new Pen(new SolidBrush(Color.FromArgb(220, 220, 220))), 0 + i, 0, 0 + i, this.Height);
                g.DrawLine(new Pen(new SolidBrush(Color.FromArgb(220, 220, 220))), 0, 0 + i, this.Width, i);
            }           
                Point p = new Point(textX, textY);
                SolidBrush frcolor = new SolidBrush(this.ForeColor);
                g.DrawString(text, this.Font, frcolor, p);           

            b.Dispose();
        }




        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            this.DrawRectangularButton(e.Graphics);            
        }



    }

More read about this

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-29
    • 1970-01-01
    相关资源
    最近更新 更多