Access DataGridView rows in the order they are added

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; } } } } 
+6
source share
1 answer

You can try using the Tag property of a string to place the row index number. This is how I initialized my DataGridView:

 dataGridView1.Rows.Add(3); for (int i = 0; i < 3; i++) { dataGridView1.Rows[i].Tag = i; dataGridView1.Rows[i].Cells[0].Value = "Name " + i.ToString(); dataGridView1.Rows[i].Cells[1].Value = "Label " + i.ToString(); } 

Here is my version of your UpdateColors procedure:

 private void UpdateColors() { String[] sStates = new String[] { }; if (m_States != null) { sStates = m_States.Split(';'); for (int i = 0; i < sStates.Length;i++) { int nState = Convert.ToInt32(sStates[i]); foreach (DataGridViewRow row in dataGridView1.Rows) { int rowIndex = Convert.ToInt32(row.Tag); if (rowIndex == i) { row.DefaultCellStyle.BackColor = m_Couleurs_Fond_Etats[nState]; } } } } } 

I first iterate over your split status bar to get the row index and convert the actual value to a color index. Then I look through the lines to find a suitable index property that I placed in the Tag property.

Here is a cleaned version using only one loop:

 private void UpdateColors() { String[] sStates = new String[] { }; if (m_States != null) { sStates = m_States.Split(';'); foreach (DataGridViewRow row in dataGridView1.Rows) { int rowIndex = Convert.ToInt32(row.Tag); int colorIndex = Convert.ToInt32(sStates[rowIndex]); row.DefaultCellStyle.BackColor = m_Couleurs_Fond_Etats[colorIndex]; } } } 

Error checking required.

+4
source

Source: https://habr.com/ru/post/918736/


All Articles