New to Telerik UI for WinForms? Download free 30-day trial

How to Customize Rating column

Environment

Product Version 2019.2.618
Product RadGridView for WinForms
Author Nadya Karaivanova

Description

By default, GridViewRatingColumn supports star-shaped elements (RatingStarVisualElements). A common requirement is to change the shape, e.g. use heart rating elements and apply a certain style to the hover and value elements of the rating.

Star-shaped rating elements

customize-rating-column001

Solution

Following this article for creating custom cell elements, we will create a derivative of the GridViewRatingColumn which uses a custom defined cell element that contains a RadRatingElement with 5 RatingHeartVisualElements. The main steps that need to be performed are:

  1. Create a cusom column class that inherits from GridViewRatingColumn. Override its GetCellType mehtod to replace the default data cell element with the custom one.
  2. Create a derivative of the GridDataCellElement and in the CreateChildElements method add the RadRatingElement containing 5 RatingHeartVisualElements. Ensure that the cell's value is properly updated when you select a new value from the rating element.
  3. Overriding the IsEditable property ensures that the cell won't enter edit mode since the rating element offers a permanent one.
  4. Synchronize the GridViewRatingColumn's specific properties with the rating element in the OnColumnPropertyChanged method.
  5. Also, we will handle the CellFormatting event where to apply red color for the value element and yellow one for the hover element. The background color for the entire rating element will be changed to gray.

You can find below a complete code snippet which result is illustrated in the below screenshot:

Heart-shaped rating elements

customize-rating-column002

The custom column's implementation:

Custom column


    public class CustomColumn : GridViewRatingColumn
    {
        public CustomColumn(string fieldName) : base(fieldName)
        {
        }

        public override Type GetCellType(GridViewRowInfo row)
        {
            if (row is GridViewDataRowInfo)
            {
                return typeof(CustomHeartCellElement);
            }
            return base.GetCellType(row);
        }
    }

The custom cell's implementation:

Custom cell element


    public class CustomHeartCellElement : GridDataCellElement
    {
        private RadRatingElement rating;

        public CustomHeartCellElement(GridViewColumn column, GridRowElement row)
            : base(column, row)
        {
            foreach (RatingHeartVisualElement item in this.rating.Items)
            {
                item.Margin = new Padding(0);
            }
        }

        protected override void CreateChildElements()
        {
            base.CreateChildElements();
            this.rating = new RadRatingElement();
            this.rating.StretchHorizontally = true;
            this.rating.StretchVertically = true;
            this.rating.ShouldHandleMouseInput = true;

            this.rating.CaptionElement.Visibility = ElementVisibility.Collapsed;
            this.rating.DescriptionElement.Visibility = ElementVisibility.Collapsed;
            this.rating.SubCaptionElement.Visibility = ElementVisibility.Collapsed;

            this.rating.ValueChanged += ratingElement_ValueChanged;

            for (int i = 0; i < 5; i++)
            {
                RatingHeartVisualElement heart = new RatingHeartVisualElement();
                heart.MinSize = new System.Drawing.Size(10, 10);
                this.rating.Items.Add(heart);
            }
            this.rating.IsInRadGridView = true;

            this.Children.Add(rating);
        }


        protected override void DisposeManagedResources()
        {
            base.DisposeManagedResources();

            this.rating = null;
        }


        protected override void InitializeFields()
        {
            base.InitializeFields();
            this.ShouldHandleMouseInput = false;
            this.ClipDrawing = true;
        }

        public override bool IsEditable
        {
            get
            {
                return false;
            }
        }

        public RadRatingElement RatingElement
        {
            get
            {
                return rating;
            }
        }

        private void ratingElement_ValueChanged(object sender, EventArgs e)
        {
            base.Value = this.rating.Value;
        }

        protected override void OnColumnPropertyChanged(RadPropertyChangedEventArgs e)
        {
            base.OnColumnPropertyChanged(e);

            GridViewRatingColumn column = (GridViewRatingColumn)this.ColumnInfo;

            if (e.Property == GridViewRatingColumn.MaximumProperty)
            {
                this.rating.Maximum = column.Maximum;
            }
            else if (e.Property == GridViewRatingColumn.MinimumProperty)
            {
                this.rating.Minimum = column.Minimum;
            }
            else if (e.Property == GridViewRatingColumn.ShouldPaintHoverProperty)
            {
                this.rating.ShouldPaintHover = column.ShouldPaintHover;
            }
            else if (e.Property == GridViewRatingColumn.SelectionModeProperty)
            {
                this.rating.SelectionMode = column.SelectionMode;
            }
            else if (e.Property == GridViewRatingColumn.ReadOnlyProperty)
            {
                this.rating.ReadOnly = column.ReadOnly;
            }
            else if (e.Property == GridViewRatingColumn.DirectionProperty)
            {
                this.rating.Direction = column.Direction;
            }
            else if (e.Property == GridViewRatingColumn.ToolTipPrecisionProperty)
            {
                this.rating.ToolTipPrecision = column.ToolTipPrecision;
            }
            else if (e.Property == GridViewRatingColumn.PercentageRoundingProperty)
            {
                this.rating.PercentageRounding = column.PercentageRounding;
            }
            else if (e.Property == GridViewRatingColumn.ToolTipFormatStringProperty)
            {
                this.rating.ToolTipFormatString = column.ToolTipFormatString;
            }
        }


        //Attaches the specified data.
        public override void Attach(GridViewColumn data, object context)
        {
            base.Attach(data, context);

            if (this.RowElement != null)
            {
                this.GridViewElement.EditorManager.RegisterPermanentEditorType(typeof(RadRatingElement));
            }
        }

        //Updates the information core.
        protected override void UpdateInfoCore()
        {
            base.UpdateInfoCore();

            GridViewRatingColumn column = this.ColumnInfo as GridViewRatingColumn;
            if (column != null)
            {
                this.rating.Maximum = column.Maximum;
                this.rating.Minimum = column.Minimum;
                this.rating.ShouldPaintHover = column.ShouldPaintHover;
                this.rating.SelectionMode = column.SelectionMode;
                this.rating.ReadOnly = column.ReadOnly;
                this.rating.Direction = column.Direction;
                this.rating.ToolTipPrecision = column.ToolTipPrecision;
                this.rating.PercentageRounding = column.PercentageRounding;
                this.rating.ToolTipFormatString = column.ToolTipFormatString;
            }
        }

        //Sets the actual text of the cell.
        protected override void SetContentCore(object value)
        {
            GridViewRatingColumn column = this.ColumnInfo as GridViewRatingColumn;

            if (column == null)
            {
                return;
            }

            double convertedValue = column.Minimum;
            if (value == null)
            {
                this.rating.Value = null;
            }
            else if (double.TryParse(value.ToString(), out convertedValue))
            {
                this.rating.Value = convertedValue;
            }
        }
    }

And how to use the custom column and cell:


        public Form1()
        {
            InitializeComponent();

            radGridView1.CellFormatting += RadGridView1_CellFormatting;

            CustomColumn column = new CustomColumn("Rating Column");
            radGridView1.Columns.Add(column);
            radGridView1.Rows.Add(10);
            radGridView1.Rows.Add(20);
            radGridView1.Rows.Add(30);
            radGridView1.Rows.Add(40);
            radGridView1.Rows.Add(50);
        }

        private void RadGridView1_CellFormatting(object sender, CellFormattingEventArgs e)
        {
            CustomHeartCellElement cell = e.CellElement as CustomHeartCellElement;

            if (cell != null)
            {
                cell.RatingElement.BackColor = Color.LightGray;
                cell.RatingElement.DrawFill = true;
                cell.RatingElement.GradientStyle = GradientStyles.Solid;
                foreach (RatingHeartVisualElement heart in cell.RatingElement.Items)
                {
                    heart.ValueElement.Fill.BackColor = Color.Red;
                    heart.ValueElement.Fill.GradientStyle = GradientStyles.Solid;
                    heart.HoverElement.Fill.BackColor = Color.Yellow;
                    heart.HoverElement.Fill.GradientStyle = GradientStyles.Solid;
                }
            }
        }
    }
In this article