Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Change Row background color based by cell value

Change Row background color based by cell value

Scheduled Pinned Locked Moved C#
csharphelpcsswinformstutorial
6 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • G Offline
    G Offline
    grmihel2
    wrote on last edited by
    #1

    Hi all, I have searched whole day now, for a solution that could fit my needs, yet again, I have to hope that some of your pro's here can help me getting closerto a solution. I'm using DataGridView in C# WinForms to show 6 coloumns (CustomerName, Subscribers, unsubcribed, specialCases, potential, percentage connected in %), it would look like:

    CustomerName 20 4 0 24 20/24*100=83%
    CustomerName2 12 10 1 22 12/22*100=55%

    etc. And the rows just continue basedon the number of customers of cause. Now, thats ain't any problem, and I get all my data proper as wanted. Now I want to make it a little bit more useful, and HIGHLIGHT every cell/row with a lightRed color, where the percentage is BELOW 70% (like row number 2 in my example). I have try'd with:

    private void grid_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
    {
    if (e.ListChangedType != ListChangedType.ItemDeleted)
    {
    DataGridViewCellStyle red = grid.DefaultCellStyle.Clone();
    red.BackColor = Color.LightPink;

                foreach (DataGridViewRow r in grid.Rows)
                {
                    if ((int)r.Cells\["nummer6"\].Value < 70)
                    {
                        r.DefaultCellStyle = red;
                    }
                }
    
            }
        }
    

    or with a more similar code:

    foreach (DataGridViewRow row in grid.Rows)
    {
    foreach (DataGridViewCell cell in row.Cells)
    {
    if (cell.ColumnIndex == 5)
    {
    if ((int)cell.Value < 70)
    {
    row.DefaultCellStyle.BackColor = Color.LightPink;
    }
    }
    }
    }

    But no matter what, then I can't get the backColor changed on rows where the % value in the last column cell is below 70%. :( Any ideas and help are preciated....

    H 2 Replies Last reply
    0
    • G grmihel2

      Hi all, I have searched whole day now, for a solution that could fit my needs, yet again, I have to hope that some of your pro's here can help me getting closerto a solution. I'm using DataGridView in C# WinForms to show 6 coloumns (CustomerName, Subscribers, unsubcribed, specialCases, potential, percentage connected in %), it would look like:

      CustomerName 20 4 0 24 20/24*100=83%
      CustomerName2 12 10 1 22 12/22*100=55%

      etc. And the rows just continue basedon the number of customers of cause. Now, thats ain't any problem, and I get all my data proper as wanted. Now I want to make it a little bit more useful, and HIGHLIGHT every cell/row with a lightRed color, where the percentage is BELOW 70% (like row number 2 in my example). I have try'd with:

      private void grid_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
      {
      if (e.ListChangedType != ListChangedType.ItemDeleted)
      {
      DataGridViewCellStyle red = grid.DefaultCellStyle.Clone();
      red.BackColor = Color.LightPink;

                  foreach (DataGridViewRow r in grid.Rows)
                  {
                      if ((int)r.Cells\["nummer6"\].Value < 70)
                      {
                          r.DefaultCellStyle = red;
                      }
                  }
      
              }
          }
      

      or with a more similar code:

      foreach (DataGridViewRow row in grid.Rows)
      {
      foreach (DataGridViewCell cell in row.Cells)
      {
      if (cell.ColumnIndex == 5)
      {
      if ((int)cell.Value < 70)
      {
      row.DefaultCellStyle.BackColor = Color.LightPink;
      }
      }
      }
      }

      But no matter what, then I can't get the backColor changed on rows where the % value in the last column cell is below 70%. :( Any ideas and help are preciated....

      H Offline
      H Offline
      Henry Minute
      wrote on last edited by
      #2

      I have done an experiment using the good old Northwind Database Suppliers table, modifying your code to suit Here is the code

      	private void dataGridView1\_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
      	{
      		if (e.ListChangedType != ListChangedType.ItemDeleted)
      		{
      			DataGridViewCellStyle red = dataGridView1.DefaultCellStyle.Clone();
      			red.BackColor = Color.LightPink;
      
      			foreach (DataGridViewRow r in dataGridView1.Rows)
      			{
      				if (r.Cells\["countryDataGridViewTextBoxColumn"\].Value != null)
      				{
      					if (r.Cells\["countryDataGridViewTextBoxColumn"\].Value.ToString() == "USA")
      					{
      						r.DefaultCellStyle = red;
      					}
      				}
      			}
      		}
      	}
      

      It works fine. So your problem probably lies in your if ((int)r.Cells["nummer6"].Value < 70) line. You could try something like if ((int.TryParse(r.Cells["nummer6"].Value.ToString()) < 70), although it is a bit of a kludge. I will continue experimenting and will come back to you if I find anything.

      Henry Minute Do not read medical books! You could die of a misprint. - Mark Twain Girl: (staring) "Why do you need an icy cucumber?" “I want to report a fraud. The government is lying to us all.” Why do programmers often confuse Halloween and Christmas? - Because 31 Oct = 25 Dec. Business Myths of the Geek #4 'What you think matters.'

      1 Reply Last reply
      0
      • G grmihel2

        Hi all, I have searched whole day now, for a solution that could fit my needs, yet again, I have to hope that some of your pro's here can help me getting closerto a solution. I'm using DataGridView in C# WinForms to show 6 coloumns (CustomerName, Subscribers, unsubcribed, specialCases, potential, percentage connected in %), it would look like:

        CustomerName 20 4 0 24 20/24*100=83%
        CustomerName2 12 10 1 22 12/22*100=55%

        etc. And the rows just continue basedon the number of customers of cause. Now, thats ain't any problem, and I get all my data proper as wanted. Now I want to make it a little bit more useful, and HIGHLIGHT every cell/row with a lightRed color, where the percentage is BELOW 70% (like row number 2 in my example). I have try'd with:

        private void grid_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
        {
        if (e.ListChangedType != ListChangedType.ItemDeleted)
        {
        DataGridViewCellStyle red = grid.DefaultCellStyle.Clone();
        red.BackColor = Color.LightPink;

                    foreach (DataGridViewRow r in grid.Rows)
                    {
                        if ((int)r.Cells\["nummer6"\].Value < 70)
                        {
                            r.DefaultCellStyle = red;
                        }
                    }
        
                }
            }
        

        or with a more similar code:

        foreach (DataGridViewRow row in grid.Rows)
        {
        foreach (DataGridViewCell cell in row.Cells)
        {
        if (cell.ColumnIndex == 5)
        {
        if ((int)cell.Value < 70)
        {
        row.DefaultCellStyle.BackColor = Color.LightPink;
        }
        }
        }
        }

        But no matter what, then I can't get the backColor changed on rows where the % value in the last column cell is below 70%. :( Any ideas and help are preciated....

        H Offline
        H Offline
        Henry Minute
        wrote on last edited by
        #3

        From the experiments that I have done, I can only conclude that the ValueType of your nummer6 column is not int. I would have expected the cast to int to throw an exception, but it doesn't, or at least hasn't in my tests. So, I suggest that you find out the true ValueType of your column and cast it appropriately. One way to do this is to temporarily add the following inside your foreach loop, run it once to get the type then delete it.

        if (r.Index == 0)
        {
            MessageBox.Show("Column 6 datatype is " + r.Cells\["nummer6"\].ValueType.ToString());
        }
        

        Sorry not to be more help. Good luck! :)

        Henry Minute Do not read medical books! You could die of a misprint. - Mark Twain Girl: (staring) "Why do you need an icy cucumber?" “I want to report a fraud. The government is lying to us all.” Why do programmers often confuse Halloween and Christmas? - Because 31 Oct = 25 Dec. Business Myths of the Geek #4 'What you think matters.'

        G 1 Reply Last reply
        0
        • H Henry Minute

          From the experiments that I have done, I can only conclude that the ValueType of your nummer6 column is not int. I would have expected the cast to int to throw an exception, but it doesn't, or at least hasn't in my tests. So, I suggest that you find out the true ValueType of your column and cast it appropriately. One way to do this is to temporarily add the following inside your foreach loop, run it once to get the type then delete it.

          if (r.Index == 0)
          {
              MessageBox.Show("Column 6 datatype is " + r.Cells\["nummer6"\].ValueType.ToString());
          }
          

          Sorry not to be more help. Good luck! :)

          Henry Minute Do not read medical books! You could die of a misprint. - Mark Twain Girl: (staring) "Why do you need an icy cucumber?" “I want to report a fraud. The government is lying to us all.” Why do programmers often confuse Halloween and Christmas? - Because 31 Oct = 25 Dec. Business Myths of the Geek #4 'What you think matters.'

          G Offline
          G Offline
          grmihel2
          wrote on last edited by
          #4

          Hi there, Thnx for your experimenting, making me a step closer to understand how it work behind. I'm affraid that as you say, the values ain't intergers but strings. I know that the values I have into the cells ARE intergers (count of subscribers in a interger). But seems that the parsing from string to interger won't work. Any ideas? I have decided to show some more source code, since it seems that my _databindingComplete event doesn't even trigger. Sorry for some words in danish (tell me if you need any explained):

          public partial class KundeStat_GUI : Form
          {
          private FrontController Controller = FrontController.Instance;
          //private DataGridView grid;

              private decimal fiberbyTotal\_tilmeldt = 0;
              private decimal fiberbyTotal\_utilmeldt = 0;
              private decimal fiberbytotal\_særaftale = 0;
              private decimal serviceTotal\_tilmeldt = 0;
              private decimal serviceTotal\_utilmeldt = 0;
              private decimal serviceTotal\_særaftale = 0;
              private decimal erhvervTotal\_tilmeldt = 0;
              private decimal erhvervTotal\_utilmeldt = 0;
              private decimal erhvervTotal\_særaftale = 0;
          
              public KundeStat\_GUI()
              {
                  InitializeComponent();
              }
          
              private void KundeStat\_GUI\_Load(object sender, EventArgs e)
              {
                  Dictionary<string, DataGridView> datas = new Dictionary<string, DataGridView>();
                  
          
                  foreach (Kundetype item in Controller.HentAlleKundetyper())
                  {
          	//grid are specified in KundeStat\_GUI.Designer.cs
                      grid = new DataGridView();
                      grid.Columns.Add("nummer1", "Foreningsnavn");
                      grid.Columns.Add("nummer2", "Tilmeldte");
                      grid.Columns.Add("nummer3", "Ikke tilmeldt");
                      grid.Columns.Add("nummer4", "Særaftale");
                      grid.Columns.Add("nummer5", "Potentielle");
                      grid.Columns.Add("nummer6", "% tilslutning");
          
                      grid.Columns\[0\].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
                      grid.Columns\[1\].AutoSizeMode = DataGridViewAutoSizeColumnMode.ColumnHeader;
                      grid.Columns\[2\].AutoSizeMode = DataGridViewAutoSizeColumnMode.ColumnHeader;
                      grid.Columns\[3\].AutoSizeMode = DataGridViewAutoSizeColumnMode.ColumnHeader;
                      grid.Columns\[4\].AutoSizeMode = DataGridViewAutoSizeColumnMode.ColumnHeader;
                      grid.Columns\[5\].AutoSizeMode = DataGridViewAutoSizeColumnMode.
          
          H 1 Reply Last reply
          0
          • G grmihel2

            Hi there, Thnx for your experimenting, making me a step closer to understand how it work behind. I'm affraid that as you say, the values ain't intergers but strings. I know that the values I have into the cells ARE intergers (count of subscribers in a interger). But seems that the parsing from string to interger won't work. Any ideas? I have decided to show some more source code, since it seems that my _databindingComplete event doesn't even trigger. Sorry for some words in danish (tell me if you need any explained):

            public partial class KundeStat_GUI : Form
            {
            private FrontController Controller = FrontController.Instance;
            //private DataGridView grid;

                private decimal fiberbyTotal\_tilmeldt = 0;
                private decimal fiberbyTotal\_utilmeldt = 0;
                private decimal fiberbytotal\_særaftale = 0;
                private decimal serviceTotal\_tilmeldt = 0;
                private decimal serviceTotal\_utilmeldt = 0;
                private decimal serviceTotal\_særaftale = 0;
                private decimal erhvervTotal\_tilmeldt = 0;
                private decimal erhvervTotal\_utilmeldt = 0;
                private decimal erhvervTotal\_særaftale = 0;
            
                public KundeStat\_GUI()
                {
                    InitializeComponent();
                }
            
                private void KundeStat\_GUI\_Load(object sender, EventArgs e)
                {
                    Dictionary<string, DataGridView> datas = new Dictionary<string, DataGridView>();
                    
            
                    foreach (Kundetype item in Controller.HentAlleKundetyper())
                    {
            	//grid are specified in KundeStat\_GUI.Designer.cs
                        grid = new DataGridView();
                        grid.Columns.Add("nummer1", "Foreningsnavn");
                        grid.Columns.Add("nummer2", "Tilmeldte");
                        grid.Columns.Add("nummer3", "Ikke tilmeldt");
                        grid.Columns.Add("nummer4", "Særaftale");
                        grid.Columns.Add("nummer5", "Potentielle");
                        grid.Columns.Add("nummer6", "% tilslutning");
            
                        grid.Columns\[0\].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
                        grid.Columns\[1\].AutoSizeMode = DataGridViewAutoSizeColumnMode.ColumnHeader;
                        grid.Columns\[2\].AutoSizeMode = DataGridViewAutoSizeColumnMode.ColumnHeader;
                        grid.Columns\[3\].AutoSizeMode = DataGridViewAutoSizeColumnMode.ColumnHeader;
                        grid.Columns\[4\].AutoSizeMode = DataGridViewAutoSizeColumnMode.ColumnHeader;
                        grid.Columns\[5\].AutoSizeMode = DataGridViewAutoSizeColumnMode.
            
            H Offline
            H Offline
            Henry Minute
            wrote on last edited by
            #5

            At the moment I can not see any reason why your DatabindingComplete handler doesn't fire. I will continue to look at that though. Even if that was working there are two lines in the code that you posted which are contradictory and may cause problems.

                        grid.Columns\[5\].AutoSizeMode = DataGridViewAutoSizeColumnMode.ColumnHeader;
                        **grid.Columns\[5\].ValueType = typeof(decimal);**
            
                       datas\[item.Kundetype.Type\].Rows.Add(item.KundeNavn, tilmeldte, ikketilmeldt, særaftale, tilmeldte + ikketilmeldt, **procent.ToString("###")**);
            

            In the first block you are setting the ValueType to Decimal and yet in the second you are filling it with a string procent.ToString("###"). This is incompatible. It might be better to modify the last one to simply use the result of your percentage calculation and take care of the displayed data by using the CellFormatting event of the DataGridView Like this:

                       datas\[item.Kundetype.Type\].Rows.Add(item.KundeNavn, tilmeldte, ikketilmeldt, særaftale, tilmeldte + ikketilmeldt, procent);
            

            with the CellFormatting handler something like this:

                private void grid\_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
                {
                    // Don't format if cell is null
                    if ((e.Value == DBNull.Value) || (e.Value == null))
                    {
                        return;
                    }
            
                    // If it is the 'nummer6' column
                    if (this.dataGridView1.Columns\[e.ColumnIndex\].Name == "nummer6")
                    {
                        // Format data source value and concatenate with " %"
                        string nummer6Format = e.Value.ToString("###") + " %";
            
                        // Set the display value
                        e.Value = unitPriceFormat;
            
                        // Signal that we've Formatted this value
                        e.FormattingApplied = true;    //<============================ Very important
                    }
                }
            

            This way you get to keep a numeric value in the DataGridViewCell/Column, much easier to deal with for comparisons, whilst displaying a prettified version, much easier for humans to deal with. If the DataFormattingComplete ever works you can then use your

                                if ((**decimal**)cell.Value < 70)   //<==============
            
            G 1 Reply Last reply
            0
            • H Henry Minute

              At the moment I can not see any reason why your DatabindingComplete handler doesn't fire. I will continue to look at that though. Even if that was working there are two lines in the code that you posted which are contradictory and may cause problems.

                          grid.Columns\[5\].AutoSizeMode = DataGridViewAutoSizeColumnMode.ColumnHeader;
                          **grid.Columns\[5\].ValueType = typeof(decimal);**
              
                         datas\[item.Kundetype.Type\].Rows.Add(item.KundeNavn, tilmeldte, ikketilmeldt, særaftale, tilmeldte + ikketilmeldt, **procent.ToString("###")**);
              

              In the first block you are setting the ValueType to Decimal and yet in the second you are filling it with a string procent.ToString("###"). This is incompatible. It might be better to modify the last one to simply use the result of your percentage calculation and take care of the displayed data by using the CellFormatting event of the DataGridView Like this:

                         datas\[item.Kundetype.Type\].Rows.Add(item.KundeNavn, tilmeldte, ikketilmeldt, særaftale, tilmeldte + ikketilmeldt, procent);
              

              with the CellFormatting handler something like this:

                  private void grid\_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
                  {
                      // Don't format if cell is null
                      if ((e.Value == DBNull.Value) || (e.Value == null))
                      {
                          return;
                      }
              
                      // If it is the 'nummer6' column
                      if (this.dataGridView1.Columns\[e.ColumnIndex\].Name == "nummer6")
                      {
                          // Format data source value and concatenate with " %"
                          string nummer6Format = e.Value.ToString("###") + " %";
              
                          // Set the display value
                          e.Value = unitPriceFormat;
              
                          // Signal that we've Formatted this value
                          e.FormattingApplied = true;    //<============================ Very important
                      }
                  }
              

              This way you get to keep a numeric value in the DataGridViewCell/Column, much easier to deal with for comparisons, whilst displaying a prettified version, much easier for humans to deal with. If the DataFormattingComplete ever works you can then use your

                                  if ((**decimal**)cell.Value < 70)   //<==============
              
              G Offline
              G Offline
              grmihel2
              wrote on last edited by
              #6

              Thnx a lot. I still havn't got it working yet... I'm kinda affraid that its because the dataGridView is "coded" and not drag n' drop'ed... Its just annoying to start over with code who seems too work as they are, but just not when you want this new feature. Its one of my old partners who developed the code, which is why I ain't 100% confident with it yet. If you find an answer why my event ain't triggered, plz let me know (note that this win form has a TabControl and 3 TabPages).

              1 Reply Last reply
              0
              Reply
              • Reply as topic
              Log in to reply
              • Oldest to Newest
              • Newest to Oldest
              • Most Votes


              • Login

              • Don't have an account? Register

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • World
              • Users
              • Groups