I have a DataGridView that colors its rows when the States property is set. States are a string that represents a list of numbers separated by semicolons.
If I get "0;1;2"
, the first three lines will be colored in purple, green and red respectively.
The problem occurs when I sort the datagrid by clicking on the column heading: colors apply the same way.
For instance:
Names|Labels Name1|Label1 Name2|Label2 Name3|Label3
I get "0;1;2"
, which means "Purple;Green;Red"
:
Names|Labels Name1|Label1 => Purple Name2|Label2 => Green Name3|Label3 => Red
Sort (Descending):
Names|Labels Name3|Label3 => Red Name2|Label2 => Green Name1|Label1 => Purple
I get "3;4;5"
, which means "Yellow;Orange;Pink"
:
Names|Labels Name3|Label3 => Yellow Name2|Label2 => Orange Name1|Label1 => Pink
But this is not what I expected, I wanted this:
Names|Labels Name3|Label3 => Pink Name2|Label2 => Orange Name1|Label1 => Yellow
Here is my code:
protected String m_States; public virtual String States { get { return m_States; } set { m_States = value; if (m_bRunning) { UpdateColors(); } } } private void UpdateColors() { String[] sStates = new String[] { }; if (m_States != null) { sStates = m_States.Split(m_sSeparators); int nState = 0; int nRowNumber = 0; foreach (System.Windows.Forms.DataGridViewRow row in Rows) { nState = int.Parse(sStates[nRowNumber]); if (nState < 0 || nState > m_Couleurs_Fond_Etats.Length) { nState = m_Couleurs_Fond_Etats.Length - 1; } row.DefaultCellStyle.BackColor = m_Couleurs_Fond_Etats[nState]; row.DefaultCellStyle.ForeColor = m_Couleurs_Texte_Etats[nState]; row.DefaultCellStyle.SelectionBackColor = m_Couleurs_Sel_Fond_Etats[nState]; row.DefaultCellStyle.SelectionForeColor = m_Couleurs_Sel_Texte_Etats[nState]; nState = 0; ++nRowNumber; } } }
Is there a way to access the rows in the order they are added to the DataGridView?
PS: I first used row.Index instead of nRowNumber, so I figured the problem came from this, but it seems the Rows collection has been reorganized or foreach parses it according to rowIndexes.
===== Here is the solution I used thanks to the answer of LarsTech =====
After adding my lines, I marked them as follows:
foreach(System.Windows.Forms.DataGridViewRow row in Rows) { row.Tag = row.Index; }
Then I could use this tag as the line number:
private void UpdateColors() { String[] sStates = new String[] { }; if (m_States != null) { sStates = m_States.Split(m_sSeparators); int nState = 0; int nRowNumber = 0; foreach (System.Windows.Forms.DataGridViewRow row in Rows) { nRowNumber = Convert.ToInt32(row.Tag); if (nRowNumber >= 0 && nRowNumber < sEtats.Length) { nState = int.Parse(sStates[nRowNumber]); if (nState < 0 || nState > m_Couleurs_Fond_Etats.Length) { nState = m_Couleurs_Fond_Etats.Length - 1; } row.DefaultCellStyle.BackColor = m_Couleurs_Fond_Etats[nState]; row.DefaultCellStyle.ForeColor = m_Couleurs_Texte_Etats[nState]; row.DefaultCellStyle.SelectionBackColor = m_Couleurs_Sel_Fond_Etats[nState]; row.DefaultCellStyle.SelectionForeColor = m_Couleurs_Sel_Texte_Etats[nState]; nState = 0; } } } }