user5046062
user5046062

Reputation:

C# - ".FillRectangle" Not Completely Filling Rectangle

I'm using the following code as just a test for how I might use a custom progress bar in the future - it actually isn't a progress bar at all, but rather a picturebox that the code draws a rectangle on, and then fills up based on a timer.

The problem is, I'm reaching 100% before the box is filled. I've tinkered around, but not been able to locate the issue. What am I doing wrong? See code below, and imgur screenshot of the behavior on my system.

Thanks.

    public partial class frmLoading : Form
{
    System.Windows.Forms.Timer tLoading = new System.Windows.Forms.Timer();
    Double pbLoadingUnit;
    int pbLoadingWIDTH, pbLoadingHEIGHT, pbLoadingComplete;

    Bitmap bmpLoading;
    Graphics gLoading;

    private void frmLoading_Load(object sender, EventArgs e)
    {
        pbLoadingWIDTH = pictureLoading.Width;
        pbLoadingHEIGHT = pictureLoading.Height;
        pbLoadingUnit = pbLoadingWIDTH / 100;
        pbLoadingComplete = 0;
        bmpLoading = new Bitmap(pbLoadingWIDTH, pbLoadingHEIGHT);
        tLoading.Interval = 32;
        tLoading.Tick += new EventHandler(this.tLoading_Tick);
        tLoading.Start();
    }
    private void tLoading_Tick(object sender, EventArgs e)
    {
        gLoading = Graphics.FromImage(bmpLoading);
        gLoading.Clear(Color.DarkSlateGray);
        gLoading.FillRectangle(Brushes.DodgerBlue, new Rectangle(0, 0, (int)(pbLoadingComplete * pbLoadingUnit), pbLoadingHEIGHT));
        gLoading.DrawString(pbLoadingComplete + "%", new Font("Segoe UI Semibold", pbLoadingHEIGHT / 2), Brushes.White, new PointF(pbLoadingWIDTH / 2 - pbLoadingHEIGHT, pbLoadingHEIGHT / 10));
        pictureLoading.Image = bmpLoading;

        pbLoadingComplete++;
        if (pbLoadingComplete > 100)
        {
            gLoading.Dispose();
            tLoading.Stop();
        }
    }

Upvotes: 0

Views: 396

Answers (3)

Nick Bullatovci
Nick Bullatovci

Reputation: 365

you have to add this variable int pbmodal; then calculate MOD of the unit

on form load add

pbmodal = pbLoadingWIDTH % 100;

when the completed is 100% add the modal.

Difference of division

`if (pbLoadingComplete > 100)

{ gLoading.FillRectangle(Brushes.DodgerBlue, new Rectangle(0, 0, (int)(pbLoadingComplete * pbLoadingUnit) + pbmodal, pbLoadingHEIGHT)); gLoading.DrawString(pbLoadingComplete-1 + "%", new Font("Segoe UI Semibold", pbLoadingHEIGHT / 2), Brushes.White, new PointF(pbLoadingWIDTH / 2 - pbLoadingHEIGHT, pbLoadingHEIGHT / 10)); pictureLoading.Image = bmpLoading; }`

Upvotes: 0

User12345
User12345

Reputation: 1582

You should change this

pbLoadingUnit = pbLoadingWIDTH / 100;

to this

pbLoadingUnit = Convert.ToDouble(pbLoadingWIDTH) / 100;

I assume your picture width is not a multiple of a hundred. With your old code, your pbLoadingUnit will be generate as integer since you divide integer to integer.

You may use this too :

double div = 100;
pbLoadingUnit = pbLoadingWIDTH / div;

OR

pbLoadingUnit = pbLoadingWIDTH / Convert.ToDouble(100);

The point is, you should get the double value of pbLoadingUnit.

For more information about numeric casting, you may see this link dotnetperls.com/numeric-casts

Upvotes: 0

Joel Legaspi Enriquez
Joel Legaspi Enriquez

Reputation: 1236

Try to put the following lines in OnResize() event of the frmLoading:

pbLoadingWIDTH = pictureLoading.Width;
pbLoadingHEIGHT = pictureLoading.Height;
pbLoadingUnit = pbLoadingWIDTH / 100; 

Chances are you're getting the initial size of the pictureLoading during Load()... and not the actual width when it shows up and displayed in your form.

Also let tloading.Start() happens when you already get the appropriate size of you pictureLoading object.

Upvotes: 0

Related Questions