简体   繁体   中英

User control progress bar

Im trying to get a usercontrol to act as a progressbar. As far as i am aware, i need to draw a new bar ontop of the old one and increase its size according to the percentage completed. I have the following code, but unfortunately the green bar is at 100% even though i set the percentage property to 0% when the control is initialized. Im assuming i have made a dumb oversight but i cant see it, any help would be appreciated. Thanks.

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Drawing;
    using System.Drawing.Drawing2D;

    namespace CustomPbar
    {
        public partial class Pbar : UserControl
        {
            private int PercentageValue;
            public int Percentage
            {
                get { return PercentageValue;}
                set 
                {   
                    PercentageValue = value;
                    this.Invalidate();
                }
            }


            public Pbar()
            {
                InitializeComponent();

                Percentage = 0;

                    using(GraphicsPath path = new GraphicsPath())
                    {
                    path.StartFigure();

                    // top left arc 
                    path.AddArc(0, 0, (10), (10), 180, 90);
                    //rect, 180, 90);

                    // top right arc 
                    path.AddArc(((this.Width) - (10)), 0, (10), (10), 270, 90);

                    // bottom right arc 
                    path.AddArc(((this.Width) - (10)), ((this.Height) - (10)), (10), (10), 0, 90);

                    // bottom left arc
                    path.AddArc(0, ((this.Height) - (10)), (10), (10), 90, 90);

                    path.CloseFigure();

                    this.Region = new Region(path);

                    this.BackColor = SystemColors.ControlLight;
                    this.BackgroundImage = new Bitmap(@"c:\users\FrazMan\Desktop\pb1.bmp");
                    this.BackgroundImageLayout = ImageLayout.Stretch;
                }
            }


            protected override void OnPaint(PaintEventArgs e)
            {
                base.OnPaint(e);

                Rectangle rect = new Rectangle(0, 0, ((this.Width)*((Percentage)/100)), this.Height);

                using (GraphicsPath gp = new GraphicsPath())
                {
                    gp.StartFigure();

                    // top left arc 
                    gp.AddArc(0, 0, (10), (10), 180, 90);

                    // top right arc 
                    gp.AddArc(((rect.Width) - (10)), 0, (10), (10), 270, 90);

                    // bottom right arc 
                    gp.AddArc(((rect.Width) - (10)), ((rect.Height) - (10)), (10), (10), 0, 90);

                    // bottom left arc
                    gp.AddArc(0, ((rect.Height) - (10)), (10), (10), 90, 90);

                    gp.CloseFigure();

                    SolidBrush greenBrush = new SolidBrush(Color.Green);

                    e.Graphics.FillPath(greenBrush, gp);

                    greenBrush.Dispose();
                }

                using(Graphics Draw = this.CreateGraphics())
                {
                    Draw.DrawString(Percentage.ToString() + "%", ProgressBar.DefaultFont, Brushes.Black, new PointF((this.Width / 2) - ((Draw.MeasureString(Percentage.ToString() + "%", ProgressBar.DefaultFont)).Width / 2.0F), 
                        (this.Height / 2) - ((Draw.MeasureString(Percentage.ToString() + "%", ProgressBar.DefaultFont)).Height / 2.0F)));
                }

            }


            protected override void OnResize(EventArgs e)
            {
                base.OnResize(e);
                this.Refresh();
            }
        }
    }

Several places you create a Rectangle , but never use it. I think you want to use the rect width and height instead of this width and height.

You should also be using e.Graphics instead of this.CreateGraphics() for drawing the percentage string.

There is a large amount of duplicate code, and I recommend you keep all drawing code in OnPaint and when you want to redraw, call this.Refresh() . It will help a lot with maintenance.

In your OnPaint method, you are using Graphics.FillPath which will fill in the entire space inside the GraphicsPath you are creating. Try using Graphics.DrawPath if you want to just draw the outline of the shape.

here is my take on custom progressbar in c#

I have % notches also, but you can get rid of them easily. works pretty good

ProgressBarExtended.cs

using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace PressdMonitorSrvMod.Custom_Control
{
    public partial class ProgressBarExtended : UserControl
    {
        //constructor
        public ProgressBarExtended()
        {
            InitializeComponent();
        }

        #region Properties

        // Create a Value property for the Progress bar
        public float Value
        {
            get { return percent; }
            set
            {
                // Maintain the Value between 0 and 100
                if (value < 0) value = 0;
                else if (value > 100) value = 100;
                percent = value;

                percentage.Text = string.Format("{0}%", value);

                //change the notch color when overdrawn
                if (value.Equals(25f))
                    notch25.BackColor = Color.White;
                else if (value.Equals(50f))
                    notch50.BackColor = Color.White;
                else if (value.Equals(75f))
                    notch75.BackColor = Color.White;
                else if (value > 0 && value < 25)
                    notch25.BackColor = notch50.BackColor = notch75.BackColor = ProgressBarColor;
                else if (value > 25 && value < 50)
                    notch50.BackColor = notch75.BackColor = ProgressBarColor;
                else if (value > 50 && value < 75)
                    notch75.BackColor = ProgressBarColor;
                //move the percentage text to the center from start
                if (percentage.Location.X < ((Width - percentage.Width)/2))
                {
                    percentage.Location = new Point((int) ((percent/100)*Width) - percentage.Width, 0);
                    percentage.Margin = new Padding(0);
                    percentage.Dock = DockStyle.None;
                    percentage.BorderStyle = BorderStyle.None;
                    percentage.AutoSize = true;
                    percentage.TextAlign = ContentAlignment.BottomCenter;
                }
                else
                {
                    //already in center, keep it in center
                    ProgressBarExtendedSizeChanged();
                }
                //redraw after changes
                Refresh();
            }
        }

        public Color ProgressBarColor { get; set; }

        public Color HighlightColor { get; set; }

        public Font LabelFont
        {
            get { return percentage.Font; }
            set { percentage.Font = value; }
        }

        public Color LabelColor
        {
            get { return percentage.ForeColor; }
            set { percentage.ForeColor = value; }
        }

        //make it readonly, hide the property
        public new BorderStyle BorderStyle;

        #endregion Properties

        #region Events

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            e.Graphics.SmoothingMode = SmoothingMode.HighSpeed;
            // Create a brush that will draw the background of the Progress bar

            using (var brush = new SolidBrush(ProgressBarColor))
                {
                using (var pen = new Pen(brush))
                    {
                    // Create a linear gradient that will be drawn over the background.
                    using (var lgBrush = new LinearGradientBrush(new Rectangle(-1, -1, Width, Height), 
                        Color.FromArgb(150, highlightColor), 
                        Color.FromArgb(10, ProgressBarColor), 
                        LinearGradientMode.Vertical))
                        {
                        // Calculate how much has the Progress bar to be filled for "x" %
                        var width = (int)((percent / 100) * Width);
                        //draw the progress bar
                        e.Graphics.FillRectangle(brush, 0, 0, width, Height);
                        e.Graphics.FillRectangle(lgBrush, 0, 0, width, Height);
                        //draw the border
                        e.Graphics.DrawRectangle(pen, 0, 0, Width - 1, Height - 1);
                        }
                    }
                }
        }

        private void ProgressBarExtendedSizeChanged()
        {
            // Maintain the label in the center of the Progress bar
            percentage.Location = new Point(Width/2 - percentage.Width/2, 0);
        }

        #endregion Helper Methods
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM