2013-03-08 21 views
10

Niedawno zacząłem uczyć się programowania w języku C#. Próbuję utworzyć GUI przy użyciu aplikacji do tworzenia formularzy w systemie Windows. Potrzebuję zaktualizować butelkę obrazu w różnych kolorach w zależności od pewnych warunków. Otrzymuję cztery odczyty czujników z tablicy elektronicznej, które są temperaturą, ciśnieniem, gęstością, objętością. Na podstawie tych wartości muszę zaktualizować butelkę obrazu. Zaprojektowałem formę okna, jak pokazano poniżej. windows form Utworzyłem cztery pola wyboru dla czterech odczytów czujników. Integruję ręczne wprowadzanie oczekiwanego poziomu Transferu i ustawianie tej wartości jako maksymalnej skali na butelce obrazu. Pola wyboru temperatury, ciśnienia i gęstości służą do oszacowania, jaka ilość istnieje w objętości. Aby oszacować ilość w objętości, użytkownik może użyć czujnika temperatury lub czujnika gęstości lub wszystkich z nich lub tylko dwóch z nich. Jeśli kliknę jedną z kontroli, użyję tylko tego czujnika, który tak czyta. Pole wyboru dla woluminu reprezentuje pobieranie dotychczasowej ilości woluminu. Mam takie warunki, aby oszacować ilość.Jak dynamicznie wypełnić ramkę graficzną

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. 

Procedura jest gdybym Zaznacz wszystkie pola wyboru trzech czujników potem mam zamiar korzystać z trzech odczytów czujników i sprawdzić warunki i to, co kiedykolwiek warunek jest spełniony i napełnić butelkę ze dotyczące koloru. Dostaję objętość, jak dużo jest obecnie transferowane i sprawdzam te warunki i zapełniam taką ilość w butelce z obrazkami podając kolor. Mam kod do rysowania ramki graficznej, gdy wprowadzam wartości ręcznie, ale nie podoba mi się użycie wartości i warunków czujnika.

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

Proszę mi pomóc, jak to zrobić. Mam kod dla pola wyboru, jak pokazano poniżej (dla wszystkich pól wyboru).

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

Proszę mi pomóc w tym zadaniu.

Zadanie polega na tym, że otrzymam objętość z woluminu, więc muszę wypełnić tyle ilości w butelce obrazkowej. całkowita ilość to ciecz lub gaz, woda lub inne, biorąc pod uwagę powyższe warunki. Na przykład mam odczyt "50" z czujnika objętości, a następnie powinienem zaktualizować butelkę z obrazem do 50 (w skali) kolorem. w tym samym czasie, o którym kolorze powinny decydować powyższe warunki. Dostaję temperaturę, ciśnienie, wartości gęstości i muszę sprawdzić, czy to "gaz", "ciecz" czy "woda". i każdy warunek jest spełniony, a następnie zapełnij do skali "50" tym kolorem.

Próbowałem jak ten

 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; 

    } 

co próbuję z wyżej kod jest: ja przechodząc trzy argumenty na „DrawVolume” metoda, która „objętość” argument ma wartość chcę wypełnić obrazu pudełko. "volumeType" to kolor dotyczący tej objętości. Skala "ucSample.Volume" w ramce graficznej.

Powyższy kod nie działa, co chcę. nie wypełnia się tak, jak chcę. na przykład mam skalę od "0 do 100" dla ramki graficznej, a ja mam "objętość" jako "50", wtedy musi ona rysować od "0 do 50", ale powyższy kod rysuje więcej niż w pobliżu "0 do 60 ". Nie wiem, dlaczego tak się dzieje. Czy używam złych obliczeń w "Zasięgu".

Edytowano.

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

Koncepcja tego zadania jest zależy głównie od dwóch czynników 1) Objętość: jest to oryginalny tom muszę rysować w polu obraz z każdego koloru dotyczące ilości mają różne warunki. Tylko jeden warunek spełni się na raz. 2) ucSample.Volume: jest to skala butelki obrazu.

Chcę zaimplementować w ten sposób. Początkowo ustawię szacunkową wielkość transferu (jestem tym, który wprowadzi ilość do czujnika), a następnie przypisze jako skalę ramki graficznej. to działa. Teraz zacznę odczyty z czujnika. Otrzymam wartość "głośności" z czujnika. wzrośnie z "0 do szacowanej objętości transferu (maksymalna skala)". na przykład: Ustawiłem szacunkową objętość transferu około "500 ml". Następnie moje zdjęcie Skala skrzynki przypisze od "0 do 500". Następnie rozpocznę odczyty czujnika i ustawię ilość w czujniku objętości. Tak więc początkowo przeleję 100 ml wody. Dlatego w ramce graficznej skrzynka z obrazem musi wypełnić się kolorem wody w skali od 0 do 100 ml. Potem przeniesie "olej" z "100 ml na 200 ml", więc tym razem warunki będą różne, więc muszę wypełnić tak: "od 0 do 100 ml z kolorem wody i od 100 ml do 200 ml z olejem" muszę wypełnić butelkę ze zdjęciem w zależności od warunków i ilości objętości.

Z powyższego kodu mogę wypełnić butelkę ze zdjęciem tylko jednym kolorem. na przykład mam wodę z "0 do 100 ml", a następnie idealnie wypełniam butelkę ze zdjęciem z odbarwiającym kolorem dla wody. następnie od "100 ml do 200 ml", a następnie wypełnia się barwnikiem olejowym w postaci "0 do 200", a nie "0 do 100 ml z kolorem wody" i "100 ml do 200 ml" z kolorem oleju.

Edytowane. Myślę, że tak wielu użytkowników nie rozumie mojej koncepcji. Bardzo mi przykro, że złe wyjaśnienie może być spowodowane moim angielskim. Próbowałem wyjaśnić wszystko, co pokazano poniżej.

Próbuję oszacować ilość przychodzącą, która pochodzi z systemu. Początkowo ustawię oczekiwaną objętość ilości (ucSample.Volume) z systemu, która zostanie przypisana jako skala do PictureBox. To działa idealnie. Mam określone warunki szacowania ilości przychodzących. Mam jeden czujnik objętości, który da nam ilość, która już pochodzi z systemu (przechowywana w zmiennej "objętość"). Aktualizuję ramkę graficzną co sekundę. Przypisałem kolor dla każdej ilości.

na przykład: Ustawiłem szacowaną głośność na "500" (ucSample.Volume = 500), a następnie uruchomię system. System wyleje płyn powoli, zajmie 30 mennic na 100 ml ilości. Kiedy system będzie przepuszczał powoli ciecz w tym czasie, odczytam gęstość, ciśnienie, temperaturę tej cieczy za pomocą czujników i sprawdzenie, który warunek jest spełniony, w zależności od stanu wybierze jeden kolor. Więc mam jeden czujnik objętości, który daje odczyt objętości, która dotychczas przechodziła przez system. Będzie aktualizowany co sekundę, na przykład do tej pory system przechodzi tylko 10 ml płynu. Tak więc pole obrazka musi aktualizować tylko do 10 w skali z uwzględnieniem koloru. Następnie przyjmijmy, że od 10 ml do 20 ml zmienia się płyn, więc warunki będą różne, więc teraz muszę wypełnić PictureBox w innym kolorze od 10 ml do 20 ml skali. (nie od 0 do 20 ml). Powinno tak być, nie trzeba zmieniać koloru poprzedniego, który wynosi od "0 do 10 ml", zachowując ten sam kolor i dodać inny kolor od "10 do 20 ml". Tak więc koncepcja jest taka, że ​​muszę zachować poprzednie tak, jak jest, i aktualizować od poprzedniego punktu końcowego.
Nie wiemy więc, co pochodzi z systemu, więc w końcu po obejrzeniu PictureBox musimy oszacować, ile ilości (ogółem) pochodziło z systemu, a także z poszczególnych ilości każdego rodzaju.
Powyższy kod nie jest aktualizowany zgodnie z powyższym opisem. Aktualizacja polega na tym, że najpierw wypełni się "zielonym" kolorem od "0 do 100 ml", a jeśli ilość zmieni się z 100 na 200, to wypełnia się innym kolorem od "0" do 200 ml ". (nie od "100 do 200".) Tracę poprzednią informację, więc jest całkowicie błędna. Muszę zachować początkowy kolor, jak to jest do tego, ile już narysował przed wszelkimi zmianami w płynie, a jeśli jakiekolwiek zmiany przyjdą, to musi zacząć od tego punktu.

Mam nadzieję, że dałem więcej jasnego wyjaśnienia. Pomóżcie mi, jeśli ktoś zrozumie moją koncepcję.

Wreszcie mam odpowiedź na to pytanie, ale mam mały problem. Mogę dynamicznie aktualizować obrazBoxBox na podstawie warunków z użyciem poniższego kodu.

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; 

    } 

Powyższy kod aktualizuje ramkę graficzną, jak pokazano poniżej.

pictureboxupdating

co chcę teraz zrobić, to „początkowo box obraz jest wypełnienie kolorem zielonym, a jeśli zmiany koloru potem następny kolor wypełnienia na szczycie poprzedniego koloru, jak pokazano na rysunku powyżej. Teraz co potrzebuję, jeśli zmienia się kolor, wówczas obecny kolor powinien zostać wypełniony dolnym brzegiem graficznym, a poprzedni kolor powinien przesunąć się do góry, koncepcja jest taka, że ​​jeśli pojawi się jakaś nowa ilość, to powinna od dołu, więc w końcu pierwszy zaktualizowany kolor dostanie butelkę od góry obrazu i ostatnia aktualizacja koloru powinna znajdować się na dole ramki graficznej:

Proszę, może mi ktoś pomóc, jak to zrobić.

+4

Ładnie sformatowany, ale tak naprawdę nie mam tutaj pytania. – Jobo

+0

@Jobo Dodałem trochę wyjaśnienia do pytania na końcu, co próbuję wdrożyć. proszę spojrzeć na to. – reddy

+0

Krótko mówiąc, określasz objętość% i kolor, który chcesz wypełnić cylindrem transferowym, a następnie wyświetlasz animację, w której widzisz cylinder transferowy, aż wypełni się określony%? – tonyjmnz

Odpowiedz

0

Zamiast używać ramki graficznej, polecam zastąpić zdarzenie OnPaint panelu i rysować bezpośrednio do niego (pamiętając, że musisz ustawić DoubleBuffered na true dla formularza, aby uniknąć migotania, aw niektórych przypadkach wywołać Refresh() lub Invalidate()).

Nie jest to bezpośrednio powiązane, ale może pomóc w ustaleniu części renderowania: GDI+ Rendering Daj mi znać, jeśli masz dodatkowe pytania.

1

Aby uzyskać taki kształt, wystarczy użyć paneli. Zmień ich BackColor, ustaw ich pozycje, szerokości i wysokości. Aktualizuj w razie potrzeby.

Powiązane problemy