最近、C# プログラミングを学び始めました。Windows フォーム アプリケーションを使用して GUI を作成しようとしています。いくつかの条件に基づいて、別の色でピクチャー ボトルを更新する必要があります。電子ボードから、温度、圧力、密度、体積の 4 つのセンサーの読み取り値を取得しています。これらの値に基づいて、画像のボトルを更新する必要があります。以下に示すように、ウィンドウフォームを設計しました。
4 つのセンサー読み取り値に対して 4 つのチェック ボックスを作成しました。最初に、予想される転送量を手動で入力し、その値をピクチャ ボトルの最大スケールとして設定します。温度、圧力、密度のチェック ボックスを使用して、量に存在する量を推定します。体積の量を推定するために、ユーザーは温度センサーまたは密度センサー、またはそれらすべて、またはそれらの 2 つだけを使用できます。1 つのチェックをクリックすると、そのセンサーの読み取り値のみが使用されます。ボリュームのチェック ボックスは、現在までに転送されたボリュームの量を取得することを表します。数量を見積もるには、このような条件があります。
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.
手順は、3 つのセンサーのチェック ボックスをすべてオンにした場合、3 つのセンサーの読み取り値を使用して、この条件と、条件が満たされているものを確認し、色に関してボトルを満たします。現在どのくらいの量が転送されているかを取得し、これらの条件を確認して、色に関してその量をピクチャー ボトルに充填します。値を手動で入力するときにピクチャボックスを描画するコードがありますが、センサーの値と条件を使用するのは好きではありません。
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」メソッドに3つの引数を渡していることです。「volumeType」はそのボリュームに関する色です。画像ボックスの「ucSample.Volume」スケール。
上記のコードは、私が望むように機能していませんでした。私が望むようにそれはいっぱいではありません。たとえば、ピクチャボックスのスケールが「0から100」で、「ボリューム」が「50」の場合、「0から50」まで描画する必要がありますが、上記のコードは「0から60」付近でそれ以上を描画しています. なぜそのようなことが起こっているのかわかりません。「ドローハイト」で間違った計算を使用していますか?
編集しました。
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();
}
このタスクの背後にある概念は、主に 2 つの変数に依存します。一度に満たされる条件は 1 つだけです。2) ucSample.Volume: これはピクチャー ボトルのスケールです。
こんな感じで実装したいです。最初に、推定転送量を設定します(私は量をセンサーに入れる人です)。次に、画像ボックスのスケールとして割り当てます。それは働いています。次に、センサーからの読み取りを開始します。センサーから「ボリューム」値を取得します。「0から推定転送量(最大スケール)」まで増加します。例: 「500 ml」前後の推定転送量を設定しました。次に、私の写真ボックスのスケールは「0から500」まで割り当てられます。次に、センサーの読み取りを開始し、数量をボリューム センサーに入力します。最初に100mlの水を移します。そのため、絵の箱は「0から100ml」の目盛りの水彩絵の具で満たされなければなりません。その後「油」を「100mlから200ml」に移します
上記のコードから、ピクチャ ボトルを 1 色だけで満たすことができます。たとえば、「0〜100ml」の水がある場合、水の色を考慮して写真のボトルを完全に満たします。それから「100mlから200ml」から「0から200」の形でオイルカラーを充填しています。「0から100mlの水彩」と「100mlから200ml」のオイルカラーではありません。
編集しました。多くのユーザーが私のコンセプトを誤解していると思います。私の英語のせいかもしれませんが、説明が下手で大変申し訳ありません。以下に示すように、最善を尽くして説明しようとしました。
システムからの入荷量を見積もろうとしています。最初に、予想される数量がシステムから (ucSample.Volume) 来るように設定します。これは、pictureBox にスケールとして割り当てられます。これは完全に機能しています。入荷数量を見積もるには一定の条件があります。システムからすでにどれだけの量が得られたかを示すボリュームセンサーが1つあります(変数「ボリューム」に保存されています)。画像ボックスを毎秒更新しています。数量ごとに色を割り当てました。
例: 推定ボリュームを「500」(ucSample.Volume=500) に設定した場合、システムを起動します。システムは液体をゆっくりと注ぎます。100ml の量で 30 ミントかかります。その際、システムが液体をゆっくりと通過させると、センサーを使用してその液体の密度、圧力、温度を読み取り、どの条件が満たされているかを確認し、条件に応じて 1 つの色を選択します。そのため、これまでシステムを通過したボリュームを読み取るボリュームセンサーが1つあります。これは毎秒更新されます。たとえば、これまでシステムは 10 ml の液体しか通過しませんでした。したがって、画像ボックスは、色に関してスケールで最大 10 までしか更新する必要がありません。次に、入ってくる液体が 10 ml から 20 ml に変化したと仮定すると、条件が異なるため、pictureBox を 10 ml から 20 ml スケールの異なる色で塗りつぶす必要があります。(0から20mlではありません)。これはこうあるべきで、前回の「0~10ml」の色はそのままで、「10~20ml」の別の色を追加する必要はありません。したがって、コンセプトは、以前のものをそのまま維持し、以前のエンドポイントから更新し続ける必要があるということです。
したがって、システムから何が来ているのかわからないので、最後に、pictureBox を確認した後、システムからの量 (合計) と、各タイプの個々の量を推定する必要があります。
上記のコードは上記のように更新されていません。最初のように更新され、「0から100ml」まで「緑」の色で塗りつぶされ、数量が100から200に変更された場合、「0から200まで」の別の色で塗りつぶされますミリリットル」。(「100から200」ではありません。)以前の情報が失われているので、完全に間違っています。最初の色を維持する必要があるのは、液体が変化する前にすでに描画されている量までであり、変化が生じた場合はその時点から開始する必要があるためです。
より明確な説明をしていただければ幸いです。誰かが私のコンセプトを理解してくれたら助けてください。
最後に、この質問に対する答えがありますが、小さな問題があります。以下のコードを使用して、条件に基づいて 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;
}
上記のコードは、下の画像のように画像ボックスを更新しています。
私が今やりたいのは、「最初は画像ボックスが緑色で塗りつぶされており、色が変わると、上の画像に示すように、次の色が前の色の上に塗りつぶされます。今必要なのは、色が変わった場合に現在のものです。色は絵びんの底で塗りつぶされ、前の色は上に移動する必要があります. 概念は、新しい量が来る場合は下からある必要があるということです. したがって、最終的に最初に更新された色が絵びんの上部に移動し、最後に更新された色が下部にある必要があります.絵びんの。
その方法を教えてください。