Condition expression from an Enum

10 posts, 0 answers
  1. Tormod
    Tormod avatar
    38 posts
    Member since:
    Apr 2009

    Posted 04 Apr 2012 Link to this post

     

     

     

    Severity is an enum type. The below XAML doesn't work. If I compare on another property of Int type, the styles are selected just fine. I also tried to compare against the underlying constant value, but no cigar. Can I use the conditionalstyleselector on an Enum type?

    <
    telerik:RadGridView ItemsSource="{Binding IssuesFound}">

     

     

     

     

    <telerik:RadGridView.RowStyleSelector>

     

     

     

     

    <telerik:ConditionalStyleSelector>

     

     

     

     

    <telerik:StyleRule Condition="Severity = Error">

     

     

     

     

    <Style TargetType="telerik:GridViewRow">

     

     

     

     

    <Setter Property="Background" Value="Red"/>

     

     

     

     

    </Style>

     

     

     

     

    </telerik:StyleRule>

     

     

     

     

    <telerik:StyleRule Condition="Severity = Warning">

     

     

     

     

    <Style TargetType="telerik:GridViewRow">

     

     

     

     

    <Setter Property="Background" Value="Yellow"/>

     

     

     

     

    </Style>

     

     

     

     

    </telerik:StyleRule>

     

     

     

     

    <telerik:StyleRule Condition="Severity = Information">

     

     

     

     

    <Style TargetType="telerik:GridViewRow">

     

     

     

     

    <Setter Property="Background" Value="Blue"/>

     

     

     

     

    </Style>

     

     

     

     

    </telerik:StyleRule>

     

     

     

     

    </telerik:ConditionalStyleSelector>

     

     

     

     

    </telerik:RadGridView.RowStyleSelector>

     

     

     

     

    </telerik:RadGridView>

     

  2. Pavel Pavlov
    Admin
    Pavel Pavlov avatar
    2039 posts

    Posted 04 Apr 2012 Link to this post

    Hello Tormod,

    The conditional style selector does  not implement logic to parse enum from string in its expression the way you expect.

    Therefore I may recommend switching to a regular style selector and do the comparison logic in the SelectStyle Method.


    All the best,
    Pavel Pavlov
    the Telerik team
    Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
  3. Tingting
    Tingting avatar
    14 posts
    Member since:
    May 2012

    Posted 02 Jul 2012 Link to this post

    Hello , 
     
        I want to group the rows of data according to their values. For exemple, if 3 lines of data have the same ID, i will group them  if not i will do nothing.  
     
            I have found a exemple like this :

                <telerik:RadGridView.RowStyleSelector>
                    <telerik:ConditionalStyleSelector>
                        <telerik:StyleRule Condition="ShipCountry = 'France'">
                            <Style TargetType="telerik:GridViewRow">
                                <Setter Property="IsExpandable" Value="True" />
                            </Style>
                        </telerik:StyleRule> 
                    </telerik:ConditionalStyleSelector>
                </telerik:RadGridView.RowStyleSelector>

    How can i replace the fixed value  here "France " with a variable  so that i can regoup the lines of data which have the same ID ?

  4. Pavel Pavlov
    Admin
    Pavel Pavlov avatar
    2039 posts

    Posted 03 Jul 2012 Link to this post

    Hello Tingting SHAN ,

    Please clarify , do you need grouping or just conditional colorizing ?


    Kind regards,
    Pavel Pavlov
    the Telerik team

    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

  5. Felipe
    Felipe avatar
    5 posts
    Member since:
    Jul 2012

    Posted 25 Jul 2012 Link to this post

    Hello,
    I have the same problem. I need grouping where data has the same id.

    It's possible?
  6. Daniel B.
    Daniel B. avatar
    18 posts
    Member since:
    Apr 2015

    Posted 22 Jun 2015 Link to this post

    Hi

     

    So ive noticed same behaivour in latest release

     

    Ive tried various combinations, for example:

     

     // In resource library
     
    <telerik:ConditionalStyleSelector x:Key="CellStyleSelecter_XStatus">
         <telerik:StyleRule Condition="LicenceStatus= LicenceStatus.Active">
             <Style TargetType="telerik:GridViewCell" BasedOn="{StaticResource CellStyle_Status_Active}"/>
         </telerik:StyleRule>
         <telerik:StyleRule Condition="LicenceStatus != LicenceStatus.Active">
             <Style TargetType="telerik:GridViewCell" BasedOn="{StaticResource CellStyle_Status_Inactive}"/>
         </telerik:StyleRule>
     </telerik:ConditionalStyleSelector>
      
     
     <telerik:ConditionalStyleSelector x:Key="CellStyleSelecter_Licences_LicenceStatus">
         <telerik:StyleRule Condition="LicenceExpires < DateTime.Now() AND LicenceStatus != 'Expired'">
             <Style TargetType="telerik:GridViewCell" BasedOn="{StaticResource CellStyle_Status_Error}"/>
         </telerik:StyleRule>
         <telerik:StyleRule Condition="LicenceStatus = 'Active'">
             <Style TargetType="telerik:GridViewCell" BasedOn="{StaticResource CellStyle_Status_Active}"/>
         </telerik:StyleRule>
         <telerik:StyleRule Condition="LicenceStatus = 'Expired' || LicenceStatus = 'Deactivated'">
             <Style TargetType="telerik:GridViewCell" BasedOn="{StaticResource CellStyle_Status_Inactive}"/>
         </telerik:StyleRule>
     </telerik:ConditionalStyleSelector>

     

    // In view


     <telerik:GridViewDataColumn DataMemberBinding="{Binding LicenceStatus}" Header="Status" CellStyleSelector="{StaticResource CellStyleSelecter_Licences_LicenceStatus}"/>

     

    But im not seeing anything work.

     

    I looked at examples in the demos and made a conditionalstyleselecter override and ect, but i have just too many conditions and styles to effectivly apply there, and i couldnt get Expressions to work the way i wanted.

     

    Here is a copy of my last version of core CellStyleSelector file before i stopped that approach

     

    public class CellStyleSelector : StyleSelector
    {
        // public Dictionary<String, Dictionary<string, Style>> conditions { get; set; }
     
     
        // Use a Dictionary mapping ColumnName to a List of ConditionalStyleRule
        Dictionary<string, List<CellStyleRule>> _Rules;
        public Dictionary<string, List<CellStyleRule>> Rules
        {
            get
            {
                if (this._Rules == null)
                {
                    this._Rules = new Dictionary<string, List<CellStyleRule>>();
                }
     
                return this._Rules;
            }
            set { this._Rules = value; }
        }
     
        public override Style SelectStyle(object item, DependencyObject container)
        {
            if (item is BaseDataModel)
            {
                GridViewCell cell = container as GridViewCell;
                var currentColumn = cell.Column as GridViewDataColumn;
                string key = currentColumn.DataMemberBinding.Path.Path;
     
     
                if (Rules.ContainsKey(key))
                {
                    foreach (CellStyleRule rule in Rules[key])
                    {
                        // Error line, not sure how to apply an expression
                        if (((BaseDataModel)item).Where (rule.Condition))
                        {
                            return rule.Style;
                        }
                    }
                }
     
            }
            return null;
        }
     
     
    }
     
     
     
    /// <summary>
    /// ConditionalStyleRule is used in CellStyleSelector and its inheriting classes.
    ///
    /// Wouldnt be too hard to modify to allow declarative if highly desired.
    ///
    /// NOTE - tried extending telerik.StyleRule, issues with setting condition value
    /// </summary>
    public class CellStyleRule
    {
        /*
        object _Value;
        public object Value
        {
            get
            {
                return this._Value;
            }
            set
            {
                this._Value = value;
            }
        }
         */
     
        // NOTE - if needing to widen use case, use <T>, but ONLY if needed
        Expression<Func<BaseDataModel, bool>> _Condition;
        public Expression<Func<BaseDataModel, bool>> Condition
        {
            get
            {
                return this._Condition;
            }
            set
            {
                this._Condition = value;
            }
        }
     
     
        Style _Style;
        public Style Style
        {
            get
            {
                return this._Style;
            }
            set
            {
                this._Style = value;
            }
        }
     
     
     
        public CellStyleRule(Expression<Func<BaseDataModel, bool>> c, string s)
        {
            var d = App.Current.FindResource(s);
            if (d != null)
                Style = d as Style;
            else
                throw new Exception("No such style resource as '" + s + "'");
     
            // Value = v;
            Condition = c;
        }
     
     
     
        /*
        public CellStyleRule(string c, string s)
        {
            var d = App.Current.FindResource(s);
            if (d != null)
                Style = d as Style;
            else
                throw new Exception("No such style resource as '" + s + "'");
     
            // TODO - test - guessing at how to do this based on telerik classes
     
            // Value = v;
            Telerik.Windows.Data.ExpressionTypeConverter converter = new Telerik.Windows.Data.ExpressionTypeConverter();
            Condition = (System.Linq.Expressions.Expression) converter.ConvertFromString(c);
     
            c.ToString();
        }
         */
    }

     

     I used that by creating inheriting classes that set the value of this.Rules in constructor, then used them as static resource where needed.

     The Dictionary wrap was to help simplify management as the tables centered around a core collection of BaseDataModel classes

     My problem with this approach is i couldnt get Expressions (item.Where) to work as couldnt find working example of Expressions or LambdaExpressions or delegate or anything without a IEnumerable

     

     

  7. Daniel B.
    Daniel B. avatar
    18 posts
    Member since:
    Apr 2015

    Posted 22 Jun 2015 Link to this post

    So i quickly did up a working version that handles JUST simple enum checks, tested just on licences but works fine

     

    Note this does NOT solve my issue as i cant perform any of the other logic checks as shown in my previous post, nor compound conditions or any other use case except simple IF(this == that)

     

    But as this does handle enums maybe it helps others, though the code really should nativle

     

    // NOTE - abstract as i havent done anything to define declarative behaivour, wouldnt be hard to work in though
    public abstract class EnumCellStyleSelector<T> : StyleSelector
    {
        public Dictionary<string, string> Styles { set; get; }
        public string PropertyName { set; get; }
     
        public override Style SelectStyle(object item, DependencyObject container)
        {
            if (item is BaseDataModel)
            {
                BaseDataModel obj = item as BaseDataModel;
                 
                foreach (string keystring in this.Styles.Keys)
                {
                    string[] keys = keystring.Split(',');
                    foreach(string k in keys)
                    {
                        // NOTE - i use my helper function to retrieve property name, but many solutions exist for this
                        var val = GeneralUtil.GetPropValue(obj,this.PropertyName);
                        if (val != null)
                        {
                            if (k.Trim() == val.ToString().Trim())
                            {
                                var d = App.Current.FindResource(this.Styles[k]);
                                if (d != null)
                                    return d as Style;
                                else
                                    throw new Exception("No such style resource as '" + this.Styles[k] + "'");
                            }
                        }
                        else
                        {
                            throw new Exception("No such property '" + this.PropertyName + "'");
                        }
     
                    }
                }
     
            }
            return base.SelectStyle(item, container);
        }
     
    }
     
     
    public class LicenceStatusCellStyleSelector : EnumCellStyleSelector<BaseDataModel>
    {
        public LicenceStatusCellStyleSelector()
            : base()
        {
            this.PropertyName = "LicenceStatus";
            this.Styles = new Dictionary<string, string>()
            {
                { "Expired, Deactivated", "CellStyle_Status_Inactive" },
                { "Active", "CellStyle_Status_Active" },
            };
        }
    }

     

    <telerik:RadGridView.Resources>
        <gridviewstyleselectors:LicenceStatusCellStyleSelector x:Key="LicenceStatusCellStyleSelector" />
    </telerik:RadGridView.Resources>
     
    ...
     
     
    <telerik:GridViewDataColumn DataMemberBinding="{Binding LicenceStatus}" Header="Status"  CellStyleSelector="{StaticResource LicenceStatusCellStyleSelector}"/>

     

     This is only a simple workaround, does not solve this issue at hand but maybe helps someone

     

    Can i please still get a reply to my previous post

  8. Daniel B.
    Daniel B. avatar
    18 posts
    Member since:
    Apr 2015

    Posted 22 Jun 2015 Link to this post

    So i looked again and moved away from linq, looked more at the Func<obj,bool>

    I have a semi-functioning version, gota go but will post it once i work out kinks

  9. Daniel B.
    Daniel B. avatar
    18 posts
    Member since:
    Apr 2015

    Posted 23 Jun 2015 Link to this post

    So here is a working implementation of a ConditonalStyleSelector type approach that I have made semi modular

    There is no code to handle declarative binding (xaml), but wouldnt be hard to mix in by looking at the Telerik Demo suites as they implement similar with declarative

    I personally prefer to use classes and direct assignment, but i can see the appeal for the other approach. 

        public class CellStyleSelector : StyleSelector
        {
            // Use a Dictionary mapping X columns to individual Lists of rules to check
            Dictionary<string, List<CellStyleRule>> _Rules;
            public Dictionary<string, List<CellStyleRule>> Rules
            {
                get
                {
                    if (this._Rules == null)
                    {
                        this._Rules = new Dictionary<string, List<CellStyleRule>>();
                    }
     
                    return this._Rules;
                }
                set { this._Rules = value; }
            }
     
            public override Style SelectStyle(object item, DependencyObject container)
            {
                if (item is BaseDataModel)
                {
                    GridViewCell cell = container as GridViewCell;
                    var currentColumn = cell.Column as GridViewDataColumn;
                    string key = currentColumn.DataMemberBinding.Path.Path;
     
     
                    if (Rules.ContainsKey(key))
                    {
                        foreach (CellStyleRule rule in Rules[key])
                        {
                            // string debug = DebugHelper.Debug(rule.Condition);
     
                            // REVERTED NOTE - if just Func<>
                            // if (rule.Condition((BaseDataModel)item))
     
                            // NOTE - if Expression<Func<>>, first compile then pass in param
                            if (rule.Condition.Compile()((BaseDataModel)item))
                            {
                                return rule.Style;
                            }
                        }
                    }
     
                }
                return null;
            }
     
     
        }
     
     
     
        /// <summary>
        /// Used in CellStyleSelector and its inheriting classes.
        ///
        /// Wouldnt be too hard to modify to allow declarative if highly desired.
        ///
        /// NOTE - tried extending telerik.StyleRule, issues with setting condition value
        /// </summary>
        public class CellStyleRule
        {
            Expression<Func<BaseDataModel, bool>> _Condition;
            public Expression<Func<BaseDataModel, bool>> Condition
            {
                get
                {
                    return this._Condition;
                }
                set
                {
                    this._Condition = value;
                }
            }
     
     
            Style _Style;
            public Style Style
            {
                get
                {
                    return this._Style;
                }
                set
                {
                    this._Style = value;
                }
            }
     
     
     
            public CellStyleRule(Expression<Func<BaseDataModel, bool>> c, string s)
            {
                var d = App.Current.FindResource(s);
                if (d != null)
                    this.Style = d as Style;
                else
                    throw new Exception("No such style resource as '" + s + "'");
     
                // Value = v;
                Condition = c;
            }
     
    }
     
     
     
     
        public class LicenceTableCellStyleSelector : CellStyleSelector
        {
            public LicenceTableCellStyleSelector()
                : base()
            {
                this.Rules = new Dictionary<string, List<CellStyleRule>>()
                {
                    { "LicenceStatus" , new List<CellStyleRule>()
                        {
                            // Always most specific rules at top
     
                            // Error catcher, leave in as visual cue just in case
                            { new CellStyleRule(x => ((Licence)x).LicenceExpires < DateTime.Now && ((Licence)x).LicenceStatus != LicenceStatus.Expired, "CellStyle_Licence_ExpiryMismatch") } ,
     
                            { new CellStyleRule(x => ((Licence)x).LicenceStatus == LicenceStatus.Active, "CellStyle_Status_Active") } ,
     
                            // Same as != Active, as only those would through this far
                            { new CellStyleRule(x => x != null, "CellStyle_Status_Inactive") } ,
     
     
                        }
                    },
                     
                    { "LicenceType" , new List<CellStyleRule>()
                        {                       
                            { new CellStyleRule(x => ((Licence)x).LicenceType == LicenceType.Full, "CellStyle_Licence_Full") } ,
                            { new CellStyleRule(x => ((Licence)x).LicenceType == LicenceType.Upgrade, "CellStyle_Licence_Upgrade") } ,
     
                            // Timed, uses fallthrough so no need to actually check unless wanting to distinct types of timed
                            { new CellStyleRule(x => x != null, "CellStyle_Status_Active") } ,
                        }
                    },
     
                    { "LicenceExpired" , new List<CellStyleRule>()
                        {                       
                            { new CellStyleRule(x => ((Licence)x).LicenceExpires < DateTime.Now && ((Licence)x).LicenceStatus != LicenceStatus.Expired, "CellStyle_Licence_ExpiryMismatch")  },
                            { new CellStyleRule(x => ((Licence)x).LicenceExpires < ((Licence)x).LicenceIssued, "CellStyle_Licence_ExpiryMismatch") } ,
                        }
                    },
                     
                    { "LicenceIssued" , new List<CellStyleRule>()
                        {
                            { new CellStyleRule(x => ((Licence)x).LicenceExpires < ((Licence)x).LicenceIssued, "CellStyle_Licence_ExpiryMismatch") } ,
                        }
                    }
                };
            }
        }

     

    <!--
        The following are styles applied to cells or rows in RadGridViews based on StyleSelectors
     
        First is generic colours, which are inherited by semi-generic flag styles, which optionally
        can be further inherited by table-specific styles (which can include tooltips and other properties)
     
        As a general rule, no colour style is applied directly, instead using semi-generic or table-specific
        styles so as to make changes easier to manage. Which style actually matches which condition is
        entirely the responsibility of the StyleSelector.
     
     
     
        <Style x:Key="CellStyle_"  TargetType="telerik:GridViewCell" BasedOn="{StaticResource GridViewCellStyle}">
            <Setter Property="Foreground" Value=""/>
        </Style>
    -->
     
    <Style x:Key="CellStyle_Green"  TargetType="telerik:GridViewCell" BasedOn="{StaticResource GridViewCellStyle}">
        <Setter Property="Foreground" Value="Green"/>
    </Style>
    <Style x:Key="CellStyle_DarkGreen"  TargetType="telerik:GridViewCell" BasedOn="{StaticResource GridViewCellStyle}">
        <Setter Property="Foreground" Value="DarkGreen"/>
    </Style>
    <Style x:Key="CellStyle_ExtraDarkGreen"  TargetType="telerik:GridViewCell" BasedOn="{StaticResource GridViewCellStyle}">
        <Setter Property="Foreground" Value="#004000"/>
    </Style>
    <Style x:Key="CellStyle_MediumBlue"  TargetType="telerik:GridViewCell" BasedOn="{StaticResource GridViewCellStyle}">
        <Setter Property="Foreground" Value="MediumBlue"/>
    </Style>
    <Style x:Key="CellStyle_DarkBlue"  TargetType="telerik:GridViewCell" BasedOn="{StaticResource GridViewCellStyle}">
        <Setter Property="Foreground" Value="DarkBlue"/>
    </Style>
    <Style x:Key="CellStyle_Purple"  TargetType="telerik:GridViewCell" BasedOn="{StaticResource GridViewCellStyle}">
        <Setter Property="Foreground" Value="Purple"/>
    </Style>
    <Style x:Key="CellStyle_Red"  TargetType="telerik:GridViewCell" BasedOn="{StaticResource GridViewCellStyle}">
        <Setter Property="Foreground" Value="Red"/>
    </Style>
    <Style x:Key="CellStyle_Crimson"  TargetType="telerik:GridViewCell" BasedOn="{StaticResource GridViewCellStyle}">
        <Setter Property="Foreground" Value="Crimson"/>
    </Style>
    <Style x:Key="CellStyle_DarkOrange"  TargetType="telerik:GridViewCell" BasedOn="{StaticResource GridViewCellStyle}">
        <Setter Property="Foreground" Value="DarkOrange"/>
    </Style>
    <Style x:Key="CellStyle_Silver"  TargetType="telerik:GridViewCell" BasedOn="{StaticResource GridViewCellStyle}">
        <Setter Property="Foreground" Value="Silver"/>
    </Style>
    <Style x:Key="CellStyle_DarkGray"  TargetType="telerik:GridViewCell" BasedOn="{StaticResource GridViewCellStyle}">
        <Setter Property="Foreground" Value="DarkGray"/>
    </Style>
    <Style x:Key="CellStyle_Gray"  TargetType="telerik:GridViewCell" BasedOn="{StaticResource GridViewCellStyle}">
        <Setter Property="Foreground" Value="Gray"/>
    </Style>
     
     
    <Style x:Key="CellStyle_Muted"  TargetType="telerik:GridViewCell" BasedOn="{StaticResource CellStyle_Gray}" />
    <Style x:Key="CellStyle_Status_Active"  TargetType="telerik:GridViewCell" BasedOn="{StaticResource CellStyle_ExtraDarkGreen}" />
    <Style x:Key="CellStyle_Status_Inactive"  TargetType="telerik:GridViewCell" BasedOn="{StaticResource CellStyle_Gray}" />
    <Style x:Key="CellStyle_Status_Warning"  TargetType="telerik:GridViewCell" BasedOn="{StaticResource CellStyle_Crimson}" />
    <Style x:Key="CellStyle_Status_Error"  TargetType="telerik:GridViewCell" BasedOn="{StaticResource CellStyle_Red}" />
     
     
    <Style x:Key="CellStyle_Licence_Full"  TargetType="telerik:GridViewCell" BasedOn="{StaticResource CellStyle_DarkBlue}" />
    <Style x:Key="CellStyle_Licence_Upgrade"  TargetType="telerik:GridViewCell" BasedOn="{StaticResource CellStyle_Purple}" />
    <Style x:Key="CellStyle_Licence_ExpiryMismatch"  TargetType="telerik:GridViewCell" BasedOn="{StaticResource CellStyle_Status_Error}">
        <Setter Property="ToolTip" Value="Expiry doesnt match Status or Issued Date"/>
    </Style>

     

    <telerik:GridViewDataColumn DataMemberBinding="{Binding LicenceType}" Header="Licence Type" />
    <telerik:GridViewDataColumn DataMemberBinding="{Binding LicenceIssued}" Header="Issued"
                                CellStyleSelector="{StaticResource LicenceTableCellStyleSelector}"/>
    <telerik:GridViewDataColumn DataMemberBinding="{Binding LicenceExpires}" Header="Expiry"
                                CellStyleSelector="{StaticResource LicenceTableCellStyleSelector}"/>
     

  10. Dimitrina
    Admin
    Dimitrina avatar
    3769 posts

    Posted 24 Jun 2015 Link to this post

    Hi,

    Thank you so much for sharing the working implementation you came up with.

    In case you still have any pending not-resolved questions, may I ask you to isolate the issue in a demo project and send it to us via a support ticket. That way we can debug it at our side and advice further.

    Regards,
    Dimitrina
    Telerik
    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 Feedback Portal and vote to affect the priority of the items
Back to Top