Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fill picture box dynamically

Tags:

c#

winforms

I have started recently to learn c# programming.I am trying to create GUI using windows form application. I need to update picture bottle with different colors based on some conditions. I am getting four sensors readings from electronic board which are temperature, Pressure, Density, Volume. Based on these values i have to update picture bottle. I have designed the windows form as shown below. windows form I have created four check boxes for four sensor readings. Intially i am entering expected Transfer volume manually and setting that value as the maximum scale on the picture bottle.Check boxes for Temperature , Pressure, Density are used to estimate which quantity exists in the volume. To estimate the quantity in volume the user can use temperature sensor or density sensor or all of them or only two of them.If i click one check then i am going to use only that sensor reading like that. The check box for volume represents getting the amount of volume transferred up to now. I have the conditions like this to estimate quantity.

1)Liquid 
 Temperature = 0 to 30 c
 Pressure =    0 to 200 bar
 Density  = 0.5 to 0.95 g/cc.
2)Gas
 Temperature = 31 to 60 c
 Pressure =    201 to 400 bar
 Density  =    0 to 0.5 g/cc.
3)Water
 Temperature = 61 to 90 c
 Pressure =    401 to 600 bar
 Density  =    0.956 to 1,15 g/cc.
4)Oil
 Temperature = 91 to 120 c
 Pressure =    601 to 800 bar
 Density  =    1.2 to 1.35 g/cc.
5)Mud
 Temperature = 121 to 150 c
 Pressure =    801 to 1000 bar
 Density  =    1.15 to 1.3 g/cc.
6)Not identified
 all the conditions failed.

The procedure is if i Tick all three sensor check boxes then i am going to use three sensor readings and check this conditions and what ever the condition is satisfied and fill the bottle with regarding color. I will get the volume how much is transferred at present and check these conditions and fill that much quantity in picture bottle with regarding color. I have the code for drawing picture-box when i enter values manually but not like using sensor values and conditions.

    private void DrawPercentages(int[] percentages, Color[] colors, float[] volumetransfer)
    {
        Bitmap bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height);
        Graphics G = Graphics.FromImage(bmp);
        // Create a Graphics object to draw on the picturebox
        //Graphics G = pictureBox1.CreateGraphics();

        // Calculate the number of pixels per 1 percent
        float pixelsPerPercent = pictureBox1.Height / volumetransfer[0];

        // Keep track of the height at which to start drawing (starting from the bottom going up)
        int drawHeight = pictureBox1.Height;

        // Loop through all percentages and draw a rectangle for each
        for (int i = 0; i < percentages.Length; i++)
        {
            // Create a brush with the current color
            SolidBrush brush = new SolidBrush(colors[i]);
            // Update the height at which the next rectangle is drawn.
            drawHeight -= (int)(pixelsPerPercent * percentages[i]);
            // Draw a filled rectangle
            G.FillRectangle(brush, 0, drawHeight, pictureBox1.Width, pixelsPerPercent * percentages[i]);
        }
        pictureBox1.Image = bmp;
    }

Please help me how to do this task. I have code for check box's is like as shown below(for all checkbox's).

 private void chkTransferTemp_CheckedChanged(object sender, EventArgs e)
    {
        if (chkTransferTemp.Checked)
        {
            Tempvalue = SystemNames.Temp.Data;
        }
    }

Please help me with this task.

The task is I will get the volume quantity from volume check box so i need to fill that much quantity in picture bottle. the total quantity is liquid or gas or water or some other by taking considerations into the above conditions. For example I have reading of "50" from volume sensor then i should update picture bottle up to 50(on scale)with color. at the same time which color is should be decided by the above conditions. I will get temperature , pressure, Density values and I need to check is it "Gas" or "liquid" or "water". and any condition is satisfied then fill up to scale "50"with that color.

I have tried like this

        public void DrawVolume(double volume, VolumeTypes volumeType, PictureBox pictureBottle)
    {
        ucSample sample = new ucSample();

        Color color = pictureBottle.BackColor;

        switch (volumeType)
        {
            case VolumeTypes.Gas: color = Color.Lime;
                break;
            case VolumeTypes.HydrocarboneLiquid: color = Color.Red;
                break;
            case VolumeTypes.Water: color = Color.Blue;
                break;
            case VolumeTypes.WaterBasedMud: color = Color.SaddleBrown;
                break;
            case VolumeTypes.OliBasedMud: color = Color.Chocolate;
                break;
            case VolumeTypes.NotIdentified: color = Color.Gray;
                break;

        }
        Bitmap bmp = new Bitmap(pictureBottle.Width, pictureBottle.Height);
        Graphics G = Graphics.FromImage(bmp);

        float pixelsPerPercent = (float)(pictureBottle.Height * (volume / ucSample.Volume));

        int drawHeight = (int)volume;
        SolidBrush brush = new SolidBrush(color);
        G.FillRectangle(brush, 0, drawHeight, pictureBottle.Width, (int)(pixelsPerPercent * volume));
        pictureBottle.Image = bmp;

    }

What i am trying from above code is: I am passing three arguments to the "DrawVolume" method which "volume" argument is the value i want to fill in picture box. "volumeType" is the color regarding that volume. "ucSample.Volume" scale of the picture box.

The above code was not working what i want. it is not filling as i want. for example i have scale from "0 to 100" for picture box and i have "volume" as "50" then it has to draw from "0 to 50" but the above code is drawing more than that around "0 to 60". I don't know why it is happening like that. Am i using any wrong calculation in "drawheight".

Edited.

    public enum VolumeTypes { Water, Gas, HydrocarboneLiquid, OliBasedMud, WaterBasedMud, NotIdentified, None }
    public VolumeTypes GetVolumeType(double density, double temprature, double pressure)
    {
        bool isDensityChecked = true;
        bool isTempratureChecked = true;
        bool isPressureChecked = true;

        bool IsGasePhase = (isDensityChecked) ? (density >= 0 && density <= 0.4) : true && (isTempratureChecked) ? (temprature >= 0 && temprature <= 30) : true &&
            (isPressureChecked) ? (pressure >= 0 && pressure <= 100) : true;
        bool isHydrocarbanliquid = (isDensityChecked) ? (density >= 0.5 && density <= 1) : true && (isTempratureChecked) ? (temprature >= 31 && temprature <= 60) : true &&
           (isPressureChecked) ? (pressure >= 101 && pressure <= 200) : true;
        bool isWater = (isDensityChecked) ? (density >= 1 && density <= 2) : true && (isTempratureChecked) ? (temprature >= 61 && temprature <= 90) : true &&
           (isPressureChecked) ? (pressure >= 201 && pressure <= 300) : true;
        bool isWaterBasedMud = (isDensityChecked) ? (density >= 2.1 && density <= 3) : true && (isTempratureChecked) ? (temprature >= 91 && temprature <= 120) : true &&
           (isPressureChecked) ? (pressure >= 301 && pressure <= 400) : true;
        bool isOilBasedMud = (isDensityChecked) ? (density >= 3.1 && density <= 4) : true && (isTempratureChecked) ? (temprature >= 121 && temprature <= 150) : true &&
           (isPressureChecked) ? (pressure >= 401 && pressure <= 500) : true;
        bool isNotIdentified = (isDensityChecked) ? (density >= 4.1 && density <= 5) : true && (isTempratureChecked) ? (temprature >= 151 && temprature <= 200) : true &&
           (isPressureChecked) ? (pressure >= 501 && pressure <= 600) : true;

        VolumeTypes volumeType = VolumeTypes.None;

        if (IsGasePhase) volumeType = VolumeTypes.Gas;
        if (isHydrocarbanliquid) volumeType = VolumeTypes.HydrocarboneLiquid;
        if (isWater) volumeType = VolumeTypes.Water;
        if (isWaterBasedMud) volumeType = VolumeTypes.WaterBasedMud;
        if (isOilBasedMud) volumeType = VolumeTypes.OliBasedMud;
        if (isNotIdentified) volumeType = VolumeTypes.NotIdentified;

        return volumeType;


    }

    public void DrawVolume(double volume, VolumeTypes volumeType, PictureBox pictureBottle)
    {
        int x, y, width, height;
        x = 0;
        ucSample sample = new ucSample();


        y = (int)((1 - (volume / ucSample.Volume)) * pictureBottle.Height);
        // MessageBox.Show(ucSample.Volume +"");
        width = pictureBottle.Width;
        height = (int)((volume / ucSample.Volume) * pictureBottle.Height);

        Color color = pictureBottle.BackColor;

        switch (volumeType)
        {
            case VolumeTypes.Gas: color = Color.Lime;
                break;
            case VolumeTypes.HydrocarboneLiquid: color = Color.Red;
                break;
            case VolumeTypes.Water: color = Color.Blue;
                break;
            case VolumeTypes.WaterBasedMud: color = Color.SaddleBrown;
                break;
            case VolumeTypes.OliBasedMud: color = Color.Chocolate;
                break;
            case VolumeTypes.NotIdentified: color = Color.Gray;
                break;

        }
        Graphics graphics = pictureBottle.CreateGraphics();
        pictureBottle.Refresh();
        Rectangle rec = new Rectangle(x, y, width, height);
        graphics.FillRectangle(new SolidBrush(color), rec);

        //Bitmap bmp = new Bitmap(pictureBottle.Width, pictureBottle.Height);
        //Graphics G = Graphics.FromImage(bmp);

        //float pixelsPerPercent = (float)(pictureBottle.Height * (volume / ucSample.Volume));

        //int drawHeight = (int)volume;
        //SolidBrush brush = new SolidBrush(color);
        //G.FillRectangle(brush, 0, drawHeight, pictureBottle.Width, (int)(pixelsPerPercent * volume));
        //pictureBottle.Image = bmp;

    }


    private void UpdateTable(AnalogSensorData data)
    {
        DataRow row = _table.Rows.Find(_recs);
        if (row == null)
        {
            row = _table.NewRow();
            row["Index"] = _recs;
            row["DateTime"] = data.Time;
            row["Time"] = data.Time.ToLongTimeString();                
            row[data.SystemName] = data.Eng;

            _logs = 1;
            _table.Rows.Add(row);
        }
        else
        {
            row[data.SystemName] = data.Eng;
            if (++_logs >= SensorUC.NumberOfActive)
            {
                int i = 1;
                double density = 0, temprature = 0, pressure = 0, volume = 0;
                foreach (var item in row.ItemArray)
                {
                    sheet.Cells[(int)_recs + 3, i].Value = item;

                    //if (i == 4)
                    //{
                    //    object densityCell = item;
                    //    density = (densityCell != null) ? (double)densityCell : 0;
                    //    MessageBox.Show("density is : " + density + "");
                    //}
                    if (i == 8)
                    {
                        object pressureCell = item;
                        pressure = (pressureCell != null) ? (double)pressureCell : 0;
                        //MessageBox.Show("pressure is : " + pressure + "");
                    }
                    else if (i == 12)
                    {
                        object tempratureCell = item;
                        temprature = (tempratureCell != null) ? (double)tempratureCell : 0;
                       // MessageBox.Show("temprature is : "+ temprature + "");
                    }
                    if (i == 11)
                    {
                        object volumeCell = item;
                        volume = (volumeCell != null) ? (double)volumeCell : 0;
                        //MessageBox.Show("Volume is : "+ volume + "");
                    }

                    i++;

                }
              VolumeTypes volumeType = GetVolumeType(density, temprature, pressure);

              DrawVolume(volume, volumeType, pictureBottle);
                book.SaveAs(_logFile);
                _recs++;

            }
        }
        if (!_list.Columns[data.SystemName].HeaderText.Equals(data.SensorName))
        {
            _table.Columns[data.SystemName].Caption = data.SensorName;
            _list.Columns[data.SystemName].HeaderText = data.SensorName;
        }
        _list.FirstDisplayedCell = _list.Rows[_list.Rows.Count - 1].Cells[0];
        _list.Update();
    }

The concept behind this task is mainly depends on two variables 1)volume : this is the original volume i need to draw in the picture box with regarding color each quantity have different conditions. Only one condition will satisfy at a time. 2)ucSample.Volume: this is the scale of picture bottle.

I want to implement like this. Initially I will set some estimated transfer volume(i am the one who putting quantity into sensor) then it will assign as the scale of picturebox. that is working. Now i will start readings from sensor. I will get "volume" value from sensor. it will increase from "0 to estimated transfer volume(max scale)". for example: I have set an estimated transfer volume around "500 ml". Then my picture Box scale will assign from "0 to 500". Then i will start the readings of sensor and i will put quantity's into volume sensor. So initially i will transfer 100 ml of water. So the picture box has to fill with water color from "0 to 100ml" scale in picture box. After that i will transfer "oil" from "100 ml to 200ml" so this time the conditions will be different so I need to fill like this " from 0 to 100 ml with water color and from 100ml to 200ml with oil color" like that i need to fill the picture bottle based on condition's and volume quantity.

From the above code i am able to fill the picture bottle with only one color. for example I have water from "0 to 100ml" then i am perfectly fill picture bottle with reagarding color for water. then from "100ml to 200ml" then it is filling with oil color form "0 to 200" not like "0 to 100ml with water color" and "100ml to 200ml" with oil color.

Edited. I think so many users misunderstand my concept. I am very sorry for the bad explanation may be because of my English. I have tried to explain my best as shown below.

I am trying to estimate the incoming quantity which is coming from the system. Initially I will set the expected volume of quantity is going to come(ucSample.Volume)from system, this will assign as a scale to pictureBox. This is working perfectly. I have certain conditions for estimating incoming quantity. I have one volume sensor which is going to give how much quantity already came from system(stored in variable "volume"). I am updating picture box every second. I have assigned color for each quantity.

for example: I have set estimated volume to "500"(ucSample.Volume=500), then i will start the system. System will pour the liquid slowly, it will take 30 mints for 100ml quantity. When system pass liquid slowly at that time i will read the density, pressure, temperature of that liquid using sensors and checking which condition is met, according condition it will select one color. So i have one volume sensor which gives reading of volume which passed through system up to now. It will update every second, for example up to now the system passes only 10 ml liquid. So picture box has to update only up to 10 in the scale with regarding color. Next suppose from 10 ml to 20 ml the incoming liquid changed so conditions will be different so now i need to fill pictureBox with different color from 10 ml to 20 ml scale. (not from 0 to 20ml). This should be like this, it won't need to change the color of previous one which is from "0 to 10 ml" keeping the same color and add different color from "10 to 20 ml". So the concept is i need to keep the previous one as it is and keep updating from the previous end point.
So we don't know what is coming from system so finally after seeing pictureBox we have to estimate how much quantity (total) came from system and as well as individual quantity of each type.
The above code is not updating as i described above, it is updating like first it will fill with "green" color from "0 to 100ml" and if quantity changed from 100 to 200 then it is filling with another color from "0 to 200 ml". (not from "100 to 200".) I am losing the previous information so it is totally wrong. I need to keep the initial color as it is up to how much it has already drawn before any changes in liquid then if any changes come it has to start from that point.

I hope i have given more clear explanation. Please help me if any one understand my concept.

Finally I have the answer for this question but i have small problem. I am able to update pictureBox dynamically based on conditions using below code.

 public void DrawVolume(double volume, VolumeTypes volumeType, PictureBox pictureBottle)
    {
        int x, y, width, height;
        x = 0;

        y = (int)((1 - (volume / ucSample.Volume)) * pictureBottle.Height) ;

        width = pictureBottle.Width;
        height = (int)((volume / ucSample.Volume) * pictureBottle.Height);

        Color color = pictureBottle.BackColor;

        switch (volumeType)
        {
            case VolumeTypes.Gas: color = Color.Lime;
                break;
            case VolumeTypes.HydrocarboneLiquid: color = Color.Red;
                break;
            case VolumeTypes.Water: color = Color.Blue;
                break;
            case VolumeTypes.WaterBasedMud: color = Color.SaddleBrown;
                break;
            case VolumeTypes.OliBasedMud: color = Color.Chocolate;
                break;
            case VolumeTypes.NotIdentified: color = Color.Gray;
                break;

        }

        int myCurrentHeight = height - lastHeight;
        if (color != currentColor)
        {  
            Rectangle rec = new Rectangle(x, y, width, myCurrentHeight);
            myRectangles.Add(new MyRectangle(rec,color));
            currentColor = color;
        }
        else 
        {
            Rectangle rec = new Rectangle(x,y,width,myCurrentHeight+myRectangles.Last<MyRectangle>().rectangle.Height);
            myRectangles.Last<MyRectangle>().rectangle = rec;
        }
        lastHeight = height;
        Bitmap bitmap = new Bitmap(Log.frmSample.PictureBottle.Width, Log.frmSample.PictureBottle.Height);
        Graphics graphics = Graphics.FromImage(bitmap);
        foreach (MyRectangle myRectangle in myRectangles)
        {
            graphics.FillRectangle(new SolidBrush(myRectangle.color), myRectangle.rectangle); 
        }
        Log.frmSample.PictureBottle.Image = bitmap;

    }

The above code is updating the picture box like as shown below image.

pictureboxupdating

what i want to do now is "initially picture box is filling with green color and if color changes then the next color is filling on the top of previous color as shown in the above image. Now what i need is if color changes then the present color should be filled with bottom of picturebottle and previous color should move upside. the concept is if any new quantity comes then it should from bottom. So finally the first updated color will goto top of picture bottle and last updated color should be at the bottom of picturebottle.

Please can any one help me how to do that.

like image 779
reddy Avatar asked Mar 08 '13 12:03

reddy


1 Answers

For a shape this simple, i'd just use a panels. Change their BackColor, set their positions, widths, heights. Update when needed.

like image 144
Nick Avatar answered Oct 22 '22 06:10

Nick