如何动态填充图片框

时间:2013-03-08 12:42:16

标签: c# winforms

我最近开始学习c#编程。我正在尝试使用Windows窗体应用程序创建GUI。 我需要根据某些条件更新不同颜色的图片瓶。我从电子板上获得了四个传感器读数,即温度,压力,密度,体积。基于这些值,我必须更新图片瓶。我设计了如下图所示的窗体。 windows form 我为四个传感器读数创建了四个复选框。我手动输入预期的传输量并将该值设置为图片瓶上的最大刻度。温度,压力,密度的检查框用于估计体积中存在的数量。为了估计体积的数量,用户可以使用温度传感器或密度传感器或全部或仅使用其中的两个。如果我点击一个检查,那么我将仅使用那样的传感器读数。卷的复选框表示获取到目前为止的传输量。 我有这样的条件来估计数量。

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.

程序是如果我勾选所有三个传感器复选框,那么我将使用三个传感器读数并检查这些条件以及满足条件的条件并用相应的颜色填充瓶子。我将获得当前传输量的多少并检查这些条件并用相关颜色填充图片瓶中的那么多数量。当我手动输入值而不是使用传感器值和条件时,我有绘制图片框的代码。

    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;
    }

请帮我完成这项任务。我有复选框的代码,如下所示(对于所有复选框)。

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

请帮我完成这项任务。

任务是我将从体积中获取体积数量复选框,所以我需要在图片瓶中填充这么多的数量。考虑到上述条件,总量是液体或气体或水或其他一些。例如,我读了&#34; 50&#34;从音量传感器然后我应该用彩色更新图片瓶50(按比例)。同时哪种颜色应由上述条件决定。我会得到温度,压力,密度值,我需要检查它是不是&#34; Gas&#34;或&#34;液体&#34;或&#34;水&#34;。并且满足任何条件,然后用该颜色填充刻度&#34; 50&#34;

我试过这样的

        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;

    }

我在上面的代码中尝试的是:我将三个参数传递给&#34; DrawVolume&#34; &#34; volume&#34;参数是我要填写图片框的值。 &#34; volumeType&#34;是该卷的颜色。 &#34; ucSample.Volume&#34;图片框的比例。

以上代码无法正常运行。它不是我想要的填充。 例如,我的规模来自&#34; 0到100&#34;对于图片框,我有&#34;音量&#34; as&#34; 50&#34;然后它必须从&#34; 0到50&#34;但是上面的代码比#34; 0到60&#34;更多。我不知道为什么会这样。我在&#34; drawheight&#34;。

中使用了任何错误的计算方法

编辑。

    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();
    }

这项任务背后的概念是 主要取决于两个变量 1)体积:这是我需要在图片框中绘制的原始体积,每种数量都有不同的颜色。一次只能满足一个条件。 2)ucSample.Volume:这是图片瓶的比例。

我想这样实现。 最初我会设置一些估计的传输量(我是将数量放入传感器的那个)然后它将指定为图片框的比例。那是有效的。 现在我将从传感器开始读数。我会得到&#34;音量&#34;传感器的价值。它将从&#34; 0增加到估计的传输量(最大比例)&#34;。 例如: 我设定的估计转移量约为500毫升&#34;。然后我的图片Box刻度将从&#34; 0到500&#34;分配。然后我将开始传感器的读数,我将把数量放入音量传感器。所以最初我会转移100毫升的水。因此,图片框必须填充从#0; 0到100ml&#34;在图片框中缩放。之后,我将转移&#34;石油&#34;从&#34; 100毫升到200毫升&#34;所以这次条件会有所不同所以我需要像这样填写#34; 0至100毫升水彩和100毫升至200毫升油色&#34;就像我需要根据条件和数量填充图片瓶。

从上面的代码我只能用一种颜色填充图片瓶。例如我从&#34; 0到100ml&#34;然后我完全填充图片瓶与水的颜色。然后从&#34; 100ml到200ml&#34;然后它填充油颜色形式&#34; 0到200&#34;不喜欢&#34; 0到100毫升的水彩&#34; &#34; 100ml至200ml&#34;有油色。

  

编辑。   我想很多用户都误解了我的观念。我很抱歉,可能是因为我的英语不好。我试图解释我的最佳状态,如下所示。

我正在尝试估算来自系统的输入数量。最初我将从系统设置预期的数量量(ucSample.Volume),这将作为比例分配给pictureBox。这很完美。我有一定的估算进货数量的条件。我有一个音量传感器,它将提供已经来自系统的数量(存储在变量&#34;音量&#34;)。我每秒都在更新图片框。我为每个数量指定了颜色。

例如: 我已经将估计的音量设置为&#34; 500&#34;(ucSample.Volume = 500),然后我将启动系统。系统将缓慢倒入液体,100ml的量需要30分钟。当系统在那时缓慢地通过液体时,我将使用传感器读取液体的密度,压力,温度并检查满足哪种条件,根据条件它将选择一种颜色。所以我有一个音量传感器,可以读取到目前为止通过系统的音量。它会每秒更新一次,例如到目前为止系统只通过10毫升液体。因此,图片框必须在比例颜色上仅更新最多10个。接下来假设从10毫升到20毫升进入的液体改变,所以条件将不同,所以现在我需要填充不同颜色的图片盒从10毫升到20毫升规模。 (不是0到20毫升)。这应该是这样的,它不需要改变前一个颜色,从&#34; 0到10毫升&#34;保持相同的颜色,并添加不同的颜色&#34; 10至20毫升&#34;。因此,我需要保持前一个原样,并从前一个终点继续更新 所以我们不知道系统会发生什么,所以最后看到pictureBox后我们必须估算系统的数量(总量)以及每种类型的个别数量。
上面的代码没有像我上面描述的那样更新,它首先更新它将填充&#34;绿色&#34;颜色来自&#34; 0到100ml&#34;如果数量从100变为200,那么它将填充来自&#34; 0到200毫升&#34;的另一种颜色。 (不是来自&#34; 100到200&#34;。)我丢失了以前的信息,所以这是完全错误的。我需要保持初始颜色,因为它在液体变化之前已经绘制了多少,然后如果有任何变化,它必须从那一点开始。

我希望我能给出更明确的解释。如果有人理解我的概念,请帮助我。

最后我得到了这个问题的答案,但我的问题很小。我可以使用下面的代码根据条件动态更新pictureBox。

 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;

    }

上面的代码正在更新图片框,如下图所示。

pictureboxupdating

我现在要做的是&#34;最初图片框填充绿色,如果颜色发生变化,则下一个颜色填充在上一个颜色的顶部,如上图所示。现在我需要的是,如果颜色发生变化,那么现在的颜色应该用picturebottle的底部填充,之前的颜色应该向上移动。这个概念是,如果有任何新的数量,那么它应该来自底部。所以最后第一个更新的颜色将转到图片瓶的顶部,最后更新的颜色应该在picturebottle的底部。

任何人都可以帮我解决这个问题。

2 个答案:

答案 0 :(得分:1)

对于这么简单的形状,我只使用面板。改变他们的BackColor,设置他们的位置,宽度,高度。需要时更新。

答案 1 :(得分:0)

我建议不要使用图片框来覆盖Panel的OnPaint事件并直接绘制它(请记住,您需要将DoubleBuffered设置为true以避免闪烁,并在某些情况下调用Refresh()或Invalidate())。

这不是直接相关的,但它可以帮助您找出渲染部分:GDI+ Rendering如果您有任何其他问题,请告诉我。