Laden...

Färben jeder 2. Column im DGV nach niedrigstem Wert

Erstellt von schorge vor 5 Jahren Letzter Beitrag vor 5 Jahren 1.211 Views
S
schorge Themenstarter:in
129 Beiträge seit 2014
vor 5 Jahren
Färben jeder 2. Column im DGV nach niedrigstem Wert

Moin,

ich habe ein DGV in dem manuell Spalten hinzugefügt werden die einen Einheitspreis und einen
Gesamtpreis beinhalten. Der niedrigere Wert bekommt die Font-Color Grün, der höhere Rot.
Funktioniert alles gut, lediglich Teile meiner GUI frieren ein und der GC sammelt sich dusselig.
Steh aber irgendwie auf dem schlauch hierbei...


private void dataGridViewPreise_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {          

            if (e.RowIndex >= 0 && e.ColumnIndex >= 0)
            {
                #region Einfärben rot grün teuer billig
                //Die letzte Zeile bleibt unberührt, hier werden die Summen addiert und ausgegeben in Rot/Grün
				//Berrechnet wird nur wenn Spalte/Column2 formatiert wird 
				
                if (e.RowIndex != dataGridViewPreise.Rows.Count - 1 && e.ColumnIndex == 2)
                {
                    int colCount = dataGridViewPreise.Columns.Count;
                    // Als Standart schwarz 
                    dataGridViewPreise.Rows[e.RowIndex].Cells[e.ColumnIndex].Style.ForeColor = Color.Black;

                    // Letzte zeile die niedrige und höchste summe berechnen und färben rot /grün 
                    decimal summe = 0;
                    decimal summeNiedrig = 0;
                    decimal summeHoch = 0;
                    int cellSummeNiedrig = 0;
                    int cellSummeHoch = 0;
					
					// fängt an bei Column6, da vorher Beschreibung etc. ausgegeben wird
                    for (int cols = 6; cols < colCount; cols++) 
                    {
						// jede zweite spalte mit dem EP
                        if (cols % 2 == 1 && dataGridViewPreise.Rows[e.RowIndex].Cells[cols].Value != null) 
                        {
                            if (dataGridViewPreise.Rows[e.RowIndex].Cells[cols].Value.ToString() != "")
                            {
                                summe = Convert.ToDecimal(dataGridViewPreise.Rows[e.RowIndex].Cells[cols].Value);

                                if (summe > summeHoch)
                                {
                                    summeHoch = summe;
                                    cellSummeHoch = cols;

                                    if (summeNiedrig == 0)
                                    {
                                        summeNiedrig = summe;
                                        cellSummeNiedrig = cols;
                                    }
                                }
                                else if (summe < summeHoch)
                                {
                                    summeNiedrig = summe;
                                    cellSummeNiedrig = cols;
                                }
                            }
                        }
                    }

                    dataGridViewPreise.Rows[e.RowIndex].Cells[cellSummeNiedrig].Style.ForeColor = Color.Green;
                    dataGridViewPreise.Rows[e.RowIndex].Cells[cellSummeHoch].Style.ForeColor = Color.Red;
                }

                #endregion
                //di Summen in der Letzen Spalte, gesondert in einer Methode berrechnet, bei CellValueChange und beim Laden
                else if (e.RowIndex == dataGridViewPreise.Rows.Count - 1 && e.ColumnIndex == 2)
                {
                    e.CellStyle.BackColor = Color.LightGray;
                    float FontSize = dataGridViewPreise.DefaultCellStyle.Font.Size;
                    string FontName = dataGridViewPreise.DefaultCellStyle.Font.FontFamily.ToString();
                    e.CellStyle.Font = new Font(FontName, FontSize + 3, FontStyle.Bold);

                    int colCount = dataGridViewPreise.Columns.Count;

                    // letzte zeile die niedrige und höchste summe bererchnen und färben rot /grün eventuell ein Bild in celle bei ep
                    decimal summe = 0;
                    decimal summeNiedrig = 0;
                    decimal summeHoch = 0;
                    int cellSummeNiedrig = 0;
                    int cellSummeHoch = 0;
                    for (int cols = 6; cols < colCount; cols++) // fängt an bei 6
                    {
                        if (cols % 2 == 1) // jede zweite spalte 
                        {
                            summe = Convert.ToDecimal(dataGridViewPreise.Rows[e.RowIndex].Cells[cols].Value);

                            if (summe > summeHoch)
                            {
                                summeHoch = summe;
                                cellSummeHoch = cols;

                                if (summeNiedrig == 0)
                                {
                                    summeNiedrig = summe;
                                    cellSummeNiedrig = cols;
                                }
                            }
                            else if (summe < summeHoch)
                            {
                                summeNiedrig = summe;
                                cellSummeNiedrig = cols;
                            }
                        }
                    }
                    dataGridViewPreise.Rows[e.RowIndex].Cells[cellSummeNiedrig].Style.ForeColor = Color.Green;
                    dataGridViewPreise.Rows[e.RowIndex].Cells[cellSummeHoch].Style.ForeColor = Color.Red;
                }
            }
        }

P
64 Beiträge seit 2011
vor 5 Jahren

Moin,

zu erst mal... Code aufräumen. Das ist ja ein Graus.

Kleiner Tip, wenn du immer nur jede zweite Spalte haben möchtest in deiner for Schleife, kannst du den Schleifenzähler auch gleich um 2 erhöhen statt im Code das abzufragen.


   for (int cols = 6; cols < colCount; cols+=2)

Zu deinem Problem: Du benutzt warscheinlich das falsche Event. CellFormatting ist nicht wirklich dafür geeignet. Das ist nur für eine einzelne Zelle gedacht.

Wann willst du denn das aufrufen? Immer wenn ein neuer Preis eingegeben wird? Dann nimm lieber was wie CellEndEdit oder CellLeave

Nachtrag. Was für eine Version vom Visual Studio benutzt du denn? Bei der Community Edition vom VS2017 ist der Profiler mit an Board. Damit kannst du gut messen, wo es hängt.

S
schorge Themenstarter:in
129 Beiträge seit 2014
vor 5 Jahren

Ok, vielen dank für den Tipp mit der Schleife...
Ich habe es nun mit einem Bool gelöst. noch die DoubleBuffered Erweiterung des DGV hinzugefügt und komme zu dem gewünschten Ergebnis.
In dem CellEndEdit-Event müsste ich ja auch alle Rows und Cells durchlaufen und hätte
die Einfärbung nicht beim Laden oder Programmgesteuerten abändern.


private bool cellFormating;


private void dataGridViewPreise_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {          

            if (e.RowIndex >= 0 && e.ColumnIndex >= 0 && !cellFormating)
            {
                #region Einfärben rot grün teuer billig
                //Die letzte Zeile bleibt unberührt, hier werden die Summen addiert und ausgegeben in Rot/Grün
				//Berrechnet wird nur wenn Spalte/Column2 formatiert wird 
				
                if (e.RowIndex != dataGridViewPreise.Rows.Count - 1 && e.ColumnIndex == 2)
                {
                    int colCount = dataGridViewPreise.Columns.Count;
                    // Als Standart schwarz 
                    dataGridViewPreise.Rows[e.RowIndex].Cells[e.ColumnIndex].Style.ForeColor = Color.Black;

                    // Letzte zeile die niedrige und höchste summe berechnen und färben rot /grün 
                    decimal summe = 0;
                    decimal summeNiedrig = 0;
                    decimal summeHoch = 0;
                    int cellSummeNiedrig = 0;
                    int cellSummeHoch = 0;
					
					// fängt an bei Column6, da vorher Beschreibung etc. ausgegeben wird
                    for (int cols = 6; cols < colCount; cols+=2) 
                    {
						if (dataGridViewPreise.Rows[e.RowIndex].Cells[cols].Value.ToString() != "")
                            {
                                summe = Convert.ToDecimal(dataGridViewPreise.Rows[e.RowIndex].Cells[cols].Value);

                                if (summe > summeHoch)
                                {
                                    summeHoch = summe;
                                    cellSummeHoch = cols;

                                    if (summeNiedrig == 0)
                                    {
                                        summeNiedrig = summe;
                                        cellSummeNiedrig = cols;
                                    }
                                }
                                else if (summe < summeHoch)
                                {
                                    summeNiedrig = summe;
                                    cellSummeNiedrig = cols;
                                }
                            }
                    }

                    dataGridViewPreise.Rows[e.RowIndex].Cells[cellSummeNiedrig].Style.ForeColor = Color.Green;
                    dataGridViewPreise.Rows[e.RowIndex].Cells[cellSummeHoch].Style.ForeColor = Color.Red;
                }

                #endregion
                //di Summen in der Letzen Spalte, gesondert in einer Methode berrechnet, bei CellValueChange und beim Laden
                else if (e.RowIndex == dataGridViewPreise.Rows.Count - 1 && e.ColumnIndex == 2)
                {
                    e.CellStyle.BackColor = Color.LightGray;
                    float FontSize = dataGridViewPreise.DefaultCellStyle.Font.Size;
                    string FontName = dataGridViewPreise.DefaultCellStyle.Font.FontFamily.ToString();
                    e.CellStyle.Font = new Font(FontName, FontSize + 3, FontStyle.Bold);

                    int colCount = dataGridViewPreise.Columns.Count;

                    // letzte zeile die niedrige und höchste summe bererchnen und färben rot /grün eventuell ein Bild in celle bei ep
                    decimal summe = 0;
                    decimal summeNiedrig = 0;
                    decimal summeHoch = 0;
                    int cellSummeNiedrig = 0;
                    int cellSummeHoch = 0;
                    for (int cols = 6; cols < colCount; cols+=2) // fängt an bei 6
                    {
                        summe = Convert.ToDecimal(dataGridViewPreise.Rows[e.RowIndex].Cells[cols].Value);

						if (summe > summeHoch)
						{
							summeHoch = summe;
							cellSummeHoch = cols;

							if (summeNiedrig == 0)
							{
								summeNiedrig = summe;
								cellSummeNiedrig = cols;
							}
						}
						else if (summe < summeHoch)
						{
							summeNiedrig = summe;
							cellSummeNiedrig = cols;
						}
                    }
					
					cellFormating = true;
                    dataGridViewPreise.Rows[e.RowIndex].Cells[cellSummeNiedrig].Style.ForeColor = Color.Green;
                    dataGridViewPreise.Rows[e.RowIndex].Cells[cellSummeHoch].Style.ForeColor = Color.Red;
                }
            }
        }
		
private void dataGridViewPreisspiegel_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
	rechneBillgsteAnbieter(e.RowIndex, e.ColumnIndex);
	cellsEingefärbt = false;
}

Zu dem Profiler ist das der Leistungsprofiler ? (Analysieren>Leistungsprofiler)

P
64 Beiträge seit 2011
vor 5 Jahren

Ihhh, deutsche Version installiert?

Ja, das ist der Leistungsprofiler. Und dann den Performance Wizard verwenden (keine Ahnung, wie der auf deutsch heißt).

Dann kannst du dein Programm starten und nach dem Beenden so ziemlich alles analysieren, was du brauchst. In deinem Fall werden wohl die Methodenaufrufe interssnt sein.

Entweder Fuchst du dich da durch oder schaust mal hier für eine kleine Einführung

Einführung in die Leistungsprofilerstellung

Hier noch mal ausführlich (englisch)
Profiling in Visual Studio