我最近开始学习 C# 编程。我正在尝试使用 Windows 窗体应用程序创建 GUI。我需要根据某些情况更新不同颜色的图片瓶。我从电子板上获得四个传感器读数,它们是温度、压力、密度、体积。基于这些值,我必须更新图片瓶。我设计了如下所示的窗口窗体。 我为四个传感器读数创建了四个复选框。最初,我手动输入预期的传输量并将该值设置为图片瓶上的最大刻度。温度、压力、密度的复选框用于估计体积中存在的量。要估计体积数量,用户可以使用温度传感器或密度传感器或全部或仅其中两个。如果我单击一个检查,那么我将只使用该传感器读数。卷的复选框表示获取到现在传输的卷的数量。我有这样的条件来估计数量。
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;
}
}
请帮我完成这项任务。
任务是我将从体积复选框中获取体积数量,因此我需要在图片瓶中填充那么多数量。考虑到上述条件,总量为液体或气体或水或其他。例如,我从音量传感器读取“50”,然后我应该将图片瓶更新到 50(按比例)颜色。同时应根据上述条件决定使用哪种颜色。我会得到温度、压力、密度值,我需要检查它是“气体”、“液体”还是“水”。并且满足任何条件然后用该颜色填充到比例“50”。
我试过这样
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;
}
我从上面的代码中尝试的是:我将三个参数传递给“DrawVolume”方法,其中“volume”参数是我要填充图片框的值。“volumeType”是关于该卷的颜色。图片框的“ucSample.Volume”比例。
上面的代码不能满足我的要求。它没有像我想要的那样填充。例如,图片框的比例从“0 到 100”,“音量”为“50”,然后它必须从“0 到 50”绘制,但上面的代码绘制的比“0 到 60”周围的要多. 我不知道为什么会这样。我在“drawheight”中使用了任何错误的计算。
已编辑。
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:这是图片瓶的比例。
我想这样实现。最初我会设置一些估计的传输量(我是将数量放入传感器的人)然后它将分配为图片框的比例。那是有效的。现在我将开始从传感器读数。我将从传感器获得“音量”值。它将从“0 增加到估计的传输量(最大规模)”。例如:我已将估计的传输量设置为“500 毫升”左右。然后我的图片框比例将从“0到500”分配。然后我将开始传感器的读数,并将数量放入体积传感器。所以最初我将转移 100 毫升水。所以图片框必须在图片框中填充“0到100ml”刻度的水彩。之后,我会将“油”从“100 毫升”转移到 200 毫升
从上面的代码中,我只能用一种颜色填充图片瓶。例如,我有“0 到 100 毫升”的水,那么我就可以完美地为图片瓶装满水的颜色。然后从“100ml 到 200ml”,然后填充油色形式“0 到 200”,而不是“0 到 100ml 用水彩”和“100ml 到 200ml”用油色。
已编辑。我想很多用户误解了我的概念。我很抱歉解释不好可能是因为我的英语。我试图解释我最好的,如下所示。
我正在尝试估计来自系统的传入数量。最初,我将设置来自系统的预期数量(ucSample.Volume),这将作为一个比例分配给图片框。这是完美的工作。我有一些估计进货量的条件。我有一个体积传感器,它将给出系统已经有多少数量(存储在变量“体积”中)。我每秒都在更新图片框。我为每个数量分配了颜色。
例如:我已将估计音量设置为“500”(ucSample.Volume=500),然后我将启动系统。系统将缓慢倒入液体,100ml 需要 30 分钟。当系统缓慢通过液体时,我将使用传感器读取该液体的密度、压力、温度并检查满足哪个条件,根据条件它将选择一种颜色。所以我有一个音量传感器,它可以读取到目前为止通过系统的音量。它将每秒更新一次,例如到目前为止,系统仅通过 10 毫升液体。所以图片框只需要在比例上更新最多 10 个颜色。接下来假设输入的液体从 10 毫升到 20 毫升发生了变化,所以条件会有所不同,所以现在我需要用 10 毫升到 20 毫升刻度的不同颜色填充图片框。(不是从 0 到 20 毫升)。这应该是这样的,它不需要改变前一个的颜色,从“0到10毫升”保持相同的颜色,并从“10到20毫升”添加不同的颜色。所以这个概念是我需要保持前一个不变并从前一个端点继续更新。
所以我们不知道来自系统的东西,所以最后在看到图片框后,我们必须估计有多少(总)来自系统,以及每种类型的个体数量。
上面的代码没有像我上面描述的那样更新,它像第一次一样更新它会用“0到100ml”的“绿色”颜色填充,如果数量从100变为200,那么它会用“0到200”的另一种颜色填充毫升”。(不是从“100 到 200”。)我丢失了以前的信息,所以这是完全错误的。我需要保持初始颜色,因为它取决于在液体发生任何变化之前它已经绘制了多少,然后如果有任何变化,它必须从那个点开始。
我希望我已经给出了更清楚的解释。如果有人理解我的概念,请帮助我。
最后我有这个问题的答案,但我有一个小问题。我可以使用以下代码根据条件动态更新图片框。
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;
}
上面的代码正在更新图片框,如下图所示。
我现在要做的是“最初图片框填充绿色,如果颜色发生变化,那么下一个颜色将填充在上一个颜色的顶部,如上图所示。现在我需要的是如果颜色发生变化那么现在颜色应该用图片瓶的底部填充,之前的颜色应该向上移动。这个概念是如果有新的数量,那么它应该从底部。所以最后第一个更新的颜色将进入图片瓶的顶部,最后更新的颜色应该在底部图片瓶。
请任何人帮助我如何做到这一点。