Conditional formatting in Grid

11 posts, 0 answers
  1. preeti
    preeti avatar
    36 posts
    Member since:
    Oct 2010

    Posted 14 Mar 2011 Link to this post

    Hi,

    I am using silverlight Radgridview Q3 version .I have implemented a functionality called Color rules where depending on a cretain condition teh grid celles forground and background color should change.These conditions are set at runtime by user and not fixed so i cannot write a datatemplate in XAML.
    Imagine user creates a rule where if the cell value is Yes then its background should be Green and If No then Red.
    Now i have this rule which i need to apply to my grid. i tried writing a converter class something like this 
    public class BackColorConverter : IValueConverter
       {
           public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
           {
               ColorRuleConfig obj = parameter as ColorRuleConfig;
               string[] strarr = obj.RuleExpression.Split(new char[]{'='});
               string strColName = strarr[0];
               string strColVal = strarr[1];
               string str = value as string;
               if(String.IsNullOrEmpty(str))
               {
                   return string.Empty;
               }
               try
               {
                   if(str == strColVal)
                   {
                       return obj.RuleBackColor.ToString();
                   }
               }
               catch
               {
               }
               return str;            
           }
           public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
           {           
               return string.Empty;
           }
       }


    and i am applying my convertor like this

     

     

    Dictionary<string, ColorRuleConfig> dictColorRuleConfig = viewmodelobj.dictColorRuleConfig;

     

     

     

     

    if (dictColorRuleConfig != null && dictColorRuleConfig.Count > 0)

     

     

    {

     

     

     

    foreach (var item in dictColorRuleConfig)

     

     

    {

     

     

     

    GridViewColumn col = dataGrid1.Columns[item.Value.ColumnName];

     

     

     

     

    Binding bindingForeColor = new Binding(item.Value.ColumnName.ToString()) { Mode = BindingMode.TwoWay, ConverterParameter = item.Value, Converter = (foreColorConvobj as IValueConverter) };

     

     

     

     

    Binding bindingBackColor = new Binding(item.Value.ColumnName.ToString()) { Mode = BindingMode.TwoWay, ConverterParameter = item.Value, Converter = (backColorConvobj as IValueConverter) };

     

     

     

     

    Style newstyle = new Style();

     

     

    newstyle.TargetType =

     

    typeof(GridViewCell);

     

     

     

     

    Setter setterback = new Setter();

     

     

    setterback.Property =

     

    Button.BackgroundProperty;

     

     

    setterback.Value = bindingBackColor;

     

     

     

    Setter setterfore = new Setter();

     

     

    setterfore.Property =

     

    Button.ForegroundProperty;

     

     

    setterfore.Value = bindingForeColor;

     

    newstyle.Setters.Add(setterback);

     

    newstyle.Setters.Add(setterfore);

     

    col.CellStyle = newstyle;

     

    }

     

    }


    But it is not applying my rules.Do you have any conditional formatting on grid column or any better way to achieve this.
  2. Ivan Ivanov
    Admin
    Ivan Ivanov avatar
    1217 posts

    Posted 14 Mar 2011 Link to this post

    Hi preeti,

    In this very case I would advise you to use a RowStyleSelector. I have prepared an example project for you (I am attaching it to my post), where users can define a "Contains" condition and set foreground and background color for all the items that satisfy it. Please, refer to is and let us know if this approach fits into your requirements.


    Regards,
    Ivan Ivanov
    the Telerik team
    Registration for Q1 2011 What’s New Webinar Week is now open. Mark your calendar for the week starting March 21st and book your seat for a walk through all the exciting stuff we ship with the new release!
  3. preeti
    preeti avatar
    36 posts
    Member since:
    Oct 2010

    Posted 15 Mar 2011 Link to this post

    Hi ,

    i want to add CellStyle selector. Instead of your row style selector. and i want to add it dynamically through code behind depending which column user has added rule. Can you tell me how this can be achieved


    void ViewModel_delApplyRuleEvent()
            {
                          
                Dictionary<string, ColorRuleConfig> dictColorRuleConfig = viewmodelobj.dictColorRuleConfig;
                if (dictColorRuleConfig != null && dictColorRuleConfig.Count > 0)
                {
                    foreach (var item in dictColorRuleConfig)
                    {
                        GridViewColumn col = dataGrid1.Columns[item.Value.ColumnName];

                        Color backcolor = new Color();
                        backcolor.A = 255;
                        backcolor.R = byte.Parse(item.Value.RuleBackColor.Substring(0, 2), NumberStyles.HexNumber);
                        backcolor.G = byte.Parse(item.Value.RuleBackColor.Substring(2, 2), NumberStyles.HexNumber);
                        backcolor.B = byte.Parse(item.Value.RuleBackColor.Substring(4, 2), NumberStyles.HexNumber);
                        SolidColorBrush BrushBackColor = new SolidColorBrush(backcolor);

                        Color forecolor = new Color();
                        forecolor.A = 255;
                        forecolor.R = byte.Parse(item.Value.RuleForeColor.Substring(0, 2), NumberStyles.HexNumber);
                        forecolor.G = byte.Parse(item.Value.RuleForeColor.Substring(2, 2), NumberStyles.HexNumber);
                        forecolor.B = byte.Parse(item.Value.RuleForeColor.Substring(4, 2), NumberStyles.HexNumber);
                        SolidColorBrush BrushForeColor = new SolidColorBrush(forecolor);
                       
                        string[] strarr = item.Value.RuleExpression.Split(new char[] { '=' });
                        string strColName = strarr[0];
                        string strColVal = strarr[1];

                        Tuple<SolidColorBrush, SolidColorBrush> ColorsProperty = Tuple.Create<SolidColorBrush, SolidColorBrush>(BrushBackColor, BrushForeColor);
                        Func<string, bool> FuncProperty= (s) => { if (s == strColVal) return true; return false; };
                        Style st = new Style(typeof(GridViewCell));
                        st.Setters.Add(new Setter(GridViewCell.BackgroundProperty, ColorsProperty.Item1));
                        st.Setters.Add(new Setter(GridViewCell.ForegroundProperty, ColorsProperty.Item2));

                        this.Resources.Add(item.Value.ColumnName + "CellStyle", st);

                        StyleSelector sc = new StyleSelector();
                        //sc.SelectStyle(dataGrid1.Columns[item.Value.ColumnName],
                        dataGrid1.Columns[item.Value.ColumnName].CellStyleSelector = sc;

                    }

                }    
            }










    public class MyStyleSelector : StyleSelector
        {
            public override Style SelectStyle(object item, DependencyObject container)
            {
                Style st = new Style(typeof(GridViewCell));
                st.Setters.Add(new Setter(GridViewCell.ForegroundProperty, SampleGrid.viewmodelobj.ColorsProperty.Item1));
                st.Setters.Add(new Setter(GridViewCell.BackgroundProperty, SampleGrid.viewmodelobj.ColorsProperty.Item2));
                return st;
            }
        }
  4. Ivan Ivanov
    Admin
    Ivan Ivanov avatar
    1217 posts

    Posted 15 Mar 2011 Link to this post

    Hello preeti,

    I have modified my previous example project to work with CellStyleSelector. Please, have a look at it. I hope this solution meets your requirements.


    Kind regards,
    Ivan Ivanov
    the Telerik team
    Registration for Q1 2011 What’s New Webinar Week is now open. Mark your calendar for the week starting March 21st and book your seat for a walk through all the exciting stuff we ship with the new release!
  5. preeti
    preeti avatar
    36 posts
    Member since:
    Oct 2010

    Posted 16 Mar 2011 Link to this post

    i have made thse changes in style code that i had pasted above.
    in my case user may set different forgaroung and background colors so i may have multipe color rules each for different columns one column. In your code there is a fixed forground and background color and a fixed function which you set at once and apply to all columns. i cant do like that. depending upon the rules defined i need to create different style for each colum with its function and fore back color.So for every rule a seperate class simailar MyStyleSelector class needs to be created and its function property and color property needs to be set.Check my code below. i have a dictonary of rules for each colum(not necessary all columns). accordingly i pick each item and create style now now to dynamically add this style to style selector and apply it to column is hwere i am stuck up.

    Dictionary<string, ColorRuleConfig> dictColorRuleConfig = viewmodelobj.dictColorRuleConfig;
               if (dictColorRuleConfig != null && dictColorRuleConfig.Count > 0)
               {
                   foreach (var item in dictColorRuleConfig)
                   {
                       GridViewColumn col = dataGrid1.Columns[item.Value.ColumnName];
                       Color backcolor = new Color();
                       backcolor.A = 255;
                       backcolor.R = byte.Parse(item.Value.RuleBackColor.Substring(0, 2), NumberStyles.HexNumber);
                       backcolor.G = byte.Parse(item.Value.RuleBackColor.Substring(2, 2), NumberStyles.HexNumber);
                       backcolor.B = byte.Parse(item.Value.RuleBackColor.Substring(4, 2), NumberStyles.HexNumber);
                       SolidColorBrush BrushBackColor = new SolidColorBrush(backcolor);
                       Color forecolor = new Color();
                       forecolor.A = 255;
                       forecolor.R = byte.Parse(item.Value.RuleForeColor.Substring(0, 2), NumberStyles.HexNumber);
                       forecolor.G = byte.Parse(item.Value.RuleForeColor.Substring(2, 2), NumberStyles.HexNumber);
                       forecolor.B = byte.Parse(item.Value.RuleForeColor.Substring(4, 2), NumberStyles.HexNumber);
                       SolidColorBrush BrushForeColor = new SolidColorBrush(forecolor);
                         
                       string[] strarr = item.Value.RuleExpression.Split(new char[] { '=' });
                       string strColName = strarr[0];
                       string strColVal = strarr[1];
                       ColorsProperty = Tuple.Create<SolidColorBrush, SolidColorBrush>(BrushBackColor, BrushForeColor);
                       FuncProperty= (s) => { if (s == strColVal) return true; return false; };
                       Style st = new Style(typeof(GridViewCell));
                       st.Setters.Add(new Setter(GridViewCell.BackgroundProperty, ColorsProperty.Item1));
                       st.Setters.Add(new Setter(GridViewCell.ForegroundProperty, ColorsProperty.Item2));
                        
                       this.Resources.Add(item.Value.ColumnName + "CellStyle", st);
                       StyleSelector sc = new StyleSelector();
                       sc.SelectStyle(dataGrid1.Columns[item.Value.ColumnName], st);*********************here i am stuck
                       dataGrid1.Columns[item.Value.ColumnName].CellStyleSelector = sc;
                        
                   }

    please let me know at the earliest.
  6. preeti
    preeti avatar
    36 posts
    Member since:
    Oct 2010

    Posted 16 Mar 2011 Link to this post

    Hi i solved the poblem by passing my color values to the Mystyleselector class.Thankyou
    public class MyStyleSelector : StyleSelector
       {
           public Tuple<SolidColorBrush, SolidColorBrush> ColorsProperty;
           public Func<string, bool> FuncProperty;
           public MyStyleSelector()
           {
                
           }
           public MyStyleSelector(Tuple<SolidColorBrush, SolidColorBrush> ColorsProperty, Func<string, bool> FuncProperty)
           {
               this.ColorsProperty = ColorsProperty;
               this.FuncProperty = FuncProperty;
           }
           public override Style SelectStyle(object item, DependencyObject container)
           {
               Style st = new Style(typeof(GridViewCell));
               st.Setters.Add(new Setter(GridViewCell.ForegroundProperty, ColorsProperty.Item1));
               st.Setters.Add(new Setter(GridViewCell.BackgroundProperty, ColorsProperty.Item2));
               return st;
           }
       }
  7. preeti
    preeti avatar
    36 posts
    Member since:
    Oct 2010

    Posted 16 Mar 2011 Link to this post

    I am facing problem when there are two conditions defined for a single column. I have a column hwere if the cell value is "Y" the the cell sould have a different fore and back color and if value is "N" then a different fore and back color .by applying the CellstyleSelector to column the later rule is overiting the previous one. I think i need to use a rowstyle selector but how do i apply to each row dynamically. Please help.
  8. Ivan Ivanov
    Admin
    Ivan Ivanov avatar
    1217 posts

    Posted 16 Mar 2011 Link to this post

    Hi preeti,

    In order to prevent this overriding, you may add several style properties to your StyleSelector implementation. So when a condition is met, its respective style will be returned.

    Best wishes,
    Ivan Ivanov
    the Telerik team
    Registration for Q1 2011 What’s New Webinar Week is now open. Mark your calendar for the week starting March 21st and book your seat for a walk through all the exciting stuff we ship with the new release!
  9. preeti
    preeti avatar
    36 posts
    Member since:
    Oct 2010

    Posted 17 Mar 2011 Link to this post

    I am not able to achieve this even after changeing conditions.
    Can you  modify your sample code to accept more than one conditions.
  10. B
    B avatar
    74 posts
    Member since:
    Jul 2011

    Posted 05 Jul 2012 Link to this post

    Hi Ivan

    With the latest upgrade I can't get dynamic colors in CellStyleSelector to work anymore. So I was looking for an example to see what has changed, but I can't find anything more recent. The SilverlightApplication23 works initially, but it doesn't change the color when the user edits the cell value.

    I modified the example to show what I need, but that gives wrong colors for cells. Is there a way to do this kind of dynamic cell coloring with the latest version of Telerik?

    But for reproducing the issue, you can also use the original SilverlightApplication23 and do the following steps:
    1.  set contains to the value of the first cell
    2. select a color, click apply
    3. Change the value of the first cell
    4. The color is still set, eventho it doesnt have a value that matches the contains text.
    5. Only when you click apply again will the color be removed.

    Regards,
    Bayram

    using System; 
    using System.Linq;
    using System.Windows;
    using System.Windows.Controls;
    using System.Collections.ObjectModel;
    using System.Windows.Media;
    using Telerik.Windows.Controls;
    using
     Telerik.Windows.Controls.GridView;
    namespace
     SilverlightApplication23 {
        public partial class MainPage : UserControl
        {
            public static MyViewModel vm = new MyViewModel();
            public MainPage()
            {
                InitializeComponent();
                LayoutRoot.DataContext = vm;
                PropertiesBox.ItemsSource = typeof(Entry).GetProperties().ToList().Select(s => s.Name);
                PropertiesBox.SelectedIndex = 0;
            }
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                vm.MatchText = containsTextBox.Text;
                MainPage.vm.ColorsProperty = Tuple.Create<SolidColorBrushSolidColorBrush>(new SolidColorBrush(ForegroundPicker.SelectedColor), new SolidColorBrush(BackgroundPicker.SelectedColor));
                MainPage.vm.FuncProperty = (s) => { if (s.GetType().GetProperty(PropertiesBox.SelectedItem.ToString()).GetValue(s, null).ToString().Contains(containsTextBox.Text)) return truereturn false; };
                 foreach(var c in testGrid.Columns)
                    (c as GridViewDataColumn).CellStyleSelector = new MyStyleSelector();
                testGrid.Rebind();
            }
        }
        public class MyStyleSelector : StyleSelector
        {
            public override Style SelectStyle(object item, DependencyObject container)
            {
                GridViewCell cell = (GridViewCell)container;
                if (cell.Value != null)
                {
                    string text = (string)cell.Value;
                    if (text.Contains(MainPage.vm.MatchText))
                    {
                        Style st = new Style(typeof(GridViewCell));
                        st.Setters.Add(new Setter(GridViewRow.ForegroundProperty, MainPage.vm.ColorsProperty.Item1));
                        st.Setters.Add(new Setter(GridViewRow.BackgroundProperty, MainPage.vm.ColorsProperty.Item2));
                        return st;
                    }
                    else
                        return null;
                }
                else
                    return null;
            }
        }
        public class Entry
        {
            public string EntryLabel1 { getset; }
            public string EntryLabel2 { getset; }
        }
        public class MyViewModel
        {
            public ObservableCollection<Entry> LabelProperty { getset; }
            public Tuple<SolidColorBrushSolidColorBrush> ColorsProperty { getset; }
            public Func<Entrybool> FuncProperty { getset; }
            public string MatchText { getset; }
            public MyViewModel()
            {
                LabelProperty = new ObservableCollection<Entry>();
                Random rnd = new Random();
                for (int i = 0; i < 100; i++)
                {
                    LabelProperty.Add(new Entry() { EntryLabel1 = rnd.Next().ToString(), EntryLabel2 = rnd.Next().ToString() });
                }
            }
        }
    }

  11. B
    B avatar
    74 posts
    Member since:
    Jul 2011

    Posted 05 Jul 2012 Link to this post

    Hi,

    I found out what the problem is with my source, you can no longer use cell.Value, it doesn't always correspond to the actual cell value.

    A workaround (or actually maybe this is a better solution) is to get the value of the property of the underlying business object (the first parameter of SelectStyle). The easiest way to achieve that is to have a different style selector for each column you want to color dynamically, then you always know which property you have to get the value of.

    Regards,
    Bayram
Back to Top