This is a migrated thread and some comments may be shown as answers.

How To Change The Color of Cell If Value Is Negative - Using a CellStyleSelector and C# in Codebehind

7 Answers 884 Views
GridView
This is a migrated thread and some comments may be shown as answers.
jgill
Top achievements
Rank 1
jgill asked on 10 Sep 2010, 01:17 AM

We are trying to set the conditional style of a RadGridView cell programatically using the CellStyleSelector however, while no errors occurs the styling is not being reflected in the grid.  Our columns in the RadGridView are populated by binding to an ObservableCollection and are not defined explicitly in XAML.

We're not sure what we are doing wrong and wanted to see if you could give us some pointers on what we're missing.

If the value in a cell is negative we would like the cell to be colored red and if the value is positive we'd like the cell to be the normal color.

//We are trying to set the style of a cell to red if it is negative and it is not working.  Value converter is working fine though.
private void GridView_AutoGenerateColumn(object sender, Telerik.Windows.Controls.GridViewAutoGeneratingColumnEventArgs e)
        {
            if (e.Column.UniqueName == "Something")
            {
                //Styles
                // Negative Style
                Style negativeStyle = new Style();
                negativeStyle.TargetType = typeof(GridViewCell);
  
                Setter backGroundSetter = new Setter();
                backGroundSetter.Property = GridViewCell.BackgroundProperty;
                backGroundSetter.Value = Brushes.Red;
                negativeStyle.Setters.Add(backGroundSetter);
  
                // Positive Style
                Style normalStyle = new Style();
                normalStyle.TargetType = typeof(GridViewCell);
  
                //Selector and Rules
                ConditionalStyleSelector selector = new ConditionalStyleSelector();
                ConditionalStyleRule negativeRule = new ConditionalStyleRule();
                negativeRule.Style = negativeStyle;
                negativeRule.Value = false;
                ConditionalStyleRule normalRule = new ConditionalStyleRule();
                negativeRule.Style = normalStyle;
                negativeRule.Value = true;
  
  
                selector.Rules.Add(negativeRule);
                selector.Rules.Add(normalRule);
                NegativeValueConverter converter = new NegativeValueConverter();
                selector.ConditionConverter = converter;
                e.Column.CellStyleSelector = selector;
            }
        }
  
  
public class NegativeValueConverter : IValueConverter
    {
        #region IValueConverter Members
  
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            SupplyAdjustmentModel converterValue = (SupplyAdjustmentModel)value;
  
            if (converterValue != null)
            {
                return converterValue.Value > 0 ? true : false;
            }
  
            return null;
        }
  
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
  
        #endregion
    }
  
/// <summary>
    /// Conditional style selector
    /// Example Usage: To conditionally style the cell in a grid based on a set of rules (e.g. negative number = red cell)
    /// </summary>
    public class ConditionalStyleSelector : StyleSelector
    {
        public override System.Windows.Style SelectStyle(object item, System.Windows.DependencyObject container)
        {
            object conditionValue = this.ConditionConverter.Convert(item, null, null, null);
            foreach (ConditionalStyleRule rule in this.Rules)
            {
                if (Equals(rule.Value, conditionValue))
                {
                    return rule.Style;
                }
            }
  
  
            return base.SelectStyle(item, container);
        }
  
        List<ConditionalStyleRule> _Rules;
        public List<ConditionalStyleRule> Rules
        {
            get
            {
                if (this._Rules == null)
                {
                    this._Rules = new List<ConditionalStyleRule>();
                }
  
                return this._Rules;
            }
        }
  
        IValueConverter _ConditionConverter;
        public IValueConverter ConditionConverter
        {
            get
            {
                return this._ConditionConverter;
            }
            set
            {
                this._ConditionConverter = value;
            }
        }
    }
  
    public class ConditionalStyleRule
    {
        object _Value;
        public object Value
        {
            get
            {
                return this._Value;
            }
            set
            {
                this._Value = value;
            }
        }
  
        Style _Style;
        public Style Style
        {
            get
            {
                return this._Style;
            }
            set
            {
                this._Style = value;
            }
        }
    }

7 Answers, 1 is accepted

Sort by
0
Maya
Telerik team
answered on 15 Sep 2010, 12:03 PM
Hi jgill,

Your code is quite correct. However, in order for it to start working, you need to change just two lines:

ConditionalStyleRule normalRule = new ConditionalStyleRule();
negativeRule.Style = normalStyle;
negativeRule.Value = true;

"negativeRule" variable should be changed to 'normalRule". 
 

Greetings,
Maya
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
jgill
Top achievements
Rank 1
answered on 15 Sep 2010, 09:19 PM
Hello, thanks for the reply.  I tried this change, but had no luck.  When the grid renders the first cell in the approriate column is colored red, but not the rest of the cells in the column.  The red background color is also not conditional as indented.  No matter what the value of the cell changes to, that one cell is always red with the others never turning red.

public GridEditor()
  {
      InitializeComponent();
      RegisterEventHandlers();
  }
  private void RegisterEventHandlers()
  {
      this.radGridView1.CellEditEnded += new EventHandler<Telerik.Windows.Controls.GridViewCellEditEndedEventArgs>(GridView_CellEditEnded);
      this.radGridView1.BeginningEdit += new EventHandler<Telerik.Windows.Controls.GridViewBeginningEditRoutedEventArgs>(GridView_BeginningEdit);
      this.radGridView1.DataLoaded += new EventHandler<EventArgs>(GridView_DataLoaded);
      this.radGridView1.AutoGeneratingColumn += new EventHandler<GridViewAutoGeneratingColumnEventArgs>(GridView_AutoGenerateColumn);
  }
  private void GridView_AutoGenerateColumn(object sender, Telerik.Windows.Controls.GridViewAutoGeneratingColumnEventArgs e)
  {
      if (e.Column.UniqueName == "Something")
      {
          //Styles
          // Negative Style
          Style negativeStyle = new Style();
          negativeStyle.TargetType = typeof(GridViewCell);
          Setter backGroundSetter = new Setter();
          backGroundSetter.Property = GridViewCell.BackgroundProperty;
          backGroundSetter.Value = Brushes.Red;
          negativeStyle.Setters.Add(backGroundSetter);
          // Positive Style
          Style normalStyle = new Style();
          normalStyle.TargetType = typeof(GridViewCell);
          //Selector and Rules
          ConditionalStyleSelector selector = new ConditionalStyleSelector();
          ConditionalStyleRule negativeRule = new ConditionalStyleRule();
          negativeRule.Style = negativeStyle;
          negativeRule.Value = false;
          ConditionalStyleRule normalRule = new ConditionalStyleRule();
          normalRule.Style = normalStyle;
          normalRule.Value = true;
          selector.Rules.Add(negativeRule);
          selector.Rules.Add(normalRule);
          NegativeValueConverter converter = new NegativeValueConverter();
          selector.ConditionConverter = converter;
          e.Column.CellStyleSelector = selector;
      }
  }
0
Jason
Top achievements
Rank 1
answered on 15 Sep 2010, 09:25 PM
put a breakpoint in your Converter to make sure it's being recalled when you change the value that you expect to trigger a cell color change.  If it's not getting hit then the RadGridView doesn't know that it needs to run the Converter again.  Your object that changes the conditional formatting value should implement INotifyPropertyChanged to allow this to happen.  If after you change the value .. you call "OnPropertyChanged("myPropertyThatJustChanged") " it should trigger the converter and cause your breakpoint to trip.

This was an excellent tutorial I read that helped me understand a little more about Converters Binding Converters Tutorial
0
Maya
Telerik team
answered on 16 Sep 2010, 08:43 AM
Hello Jason,

I have tried to reproduce the issue with colouring ontly the first cell, but unfortunately I was not able to. I am sending you the sample project I have used for testing the case.
As for the applying of the cellstyle on run-time when changing the cell value, it is not expected to be so for the time being. You may take a look at this forum thread for a further reference on that issue.

Greetings,
Maya
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
jgill
Top achievements
Rank 1
answered on 16 Sep 2010, 05:54 PM
Could you show an example of how to do this with the rebind?
0
jgill
Top achievements
Rank 1
answered on 16 Sep 2010, 06:17 PM
I need to perform a recalculation that applies to data that is on each row in the grid, e.g. a recalculation of a property of each item in an Observable Collection, so rebinding seems to be the way to go but I am getting a stack overflow in my project so I was hoping you could modify the example to show how this would be done.  Below is one example that would be similar to what I need to do.

Example: If you change the number of a player to above 10 then the Number cell for the that particular player would change color and the Country cell's for all players would change depending on a formula (e.g. if NumberofCurrentPlayer > 10 && NumberofCurrentPlayer * NumberofPreviousRowsPlayer < 30 then Country = England).
0
Maya
Telerik team
answered on 17 Sep 2010, 08:49 AM
Hi jgill,

You may refrech the grid during the RowEditEnded event like follows:

void playersGrid_RowEditEnded(object sender, GridViewRowEditEndedEventArgs e)
{
    if (e.EditAction == Telerik.Windows.Controls.GridView.GridViewEditAction.Commit)
    {
        this.playersGrid.Rebind();
    }
}

As for the second requirement for updating another column on chaning a previous one, you may take a look at this blog post.

 

Regards,
Maya
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
Tags
GridView
Asked by
jgill
Top achievements
Rank 1
Answers by
Maya
Telerik team
jgill
Top achievements
Rank 1
Jason
Top achievements
Rank 1
Share this question
or