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

Condition expression from an Enum

9 Answers 315 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Tormod
Top achievements
Rank 2
Tormod asked on 04 Apr 2012, 10:41 AM

 

 

 

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>

 

9 Answers, 1 is accepted

Sort by
0
Pavel Pavlov
Telerik team
answered on 04 Apr 2012, 01:46 PM
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 >>
0
Tingting
Top achievements
Rank 1
answered on 02 Jul 2012, 03:16 PM
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 ?

0
Pavel Pavlov
Telerik team
answered on 03 Jul 2012, 12:49 PM
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 >>

0
Felipe
Top achievements
Rank 1
answered on 25 Jul 2012, 02:48 PM
Hello,
I have the same problem. I need grouping where data has the same id.

It's possible?
0
Daniel B.
Top achievements
Rank 1
answered on 22 Jun 2015, 08:44 AM

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

 

 

0
Daniel B.
Top achievements
Rank 1
answered on 22 Jun 2015, 09:16 AM

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

0
Daniel B.
Top achievements
Rank 1
answered on 22 Jun 2015, 09:53 AM

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

0
Daniel B.
Top achievements
Rank 1
answered on 23 Jun 2015, 06:34 AM

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}"/>
 â€‹

0
Dimitrina
Telerik team
answered on 24 Jun 2015, 02:27 PM
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
Tags
GridView
Asked by
Tormod
Top achievements
Rank 2
Answers by
Pavel Pavlov
Telerik team
Tingting
Top achievements
Rank 1
Felipe
Top achievements
Rank 1
Daniel B.
Top achievements
Rank 1
Dimitrina
Telerik team
Share this question
or