GridCommandCell Element still appears disabled after it is enabled

2 posts, 1 answers
  1. Troy
    Troy avatar
    11 posts
    Member since:
    Apr 2009

    Posted 03 Jan 2012 Link to this post

    I have encountered a problem where I enabled a GridCommandCellElement in the ViewCellFormatting event handler. The cell/button is enabled but it appears disabled (grayed out). The cell/button only appears enabled (not grayed out) after the focus is shifted to the row that contains the cell/button.

    I have attached a sample project that I used to reproduce the issue. To reproduce this issue:

    1. Delete the fourth row which has a Year  of '4'. This will enable the insert ('+') button for the third row.
    2. You can click on the insert ('+') button for the third row even though it appears disabled and a new row will be inserted.
    3. If you click in the row header for the third row, the insert ('+') button, will now appear enabled.

    The issue is why does the cell/button appear to be disabled still after it has been enabled in the code.

    Here is the cs file:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
     
    using Telerik.WinControls.Primitives;
    using Telerik.WinControls.UI;
     
    namespace GridCellEnabled
    {
        public partial class Form1 : Form
        {
            private GridViewTextBoxColumn _yearColumn = null;
            private GridViewTextBoxColumn _valueColumn = null;
            private GridViewCommandColumn _insertRowColumn = null;
            private GridViewCommandColumn _deleteRowColumn = null;
     
            public Form1()
            {
                InitializeComponent();
            }
     
            private void Form1_Load(object sender, EventArgs e)
            {
                SetupGrid();
            }
     
            private void SetupGrid()
            {
                // Add Columns
                {
                    // Year Column
                    {
                        _yearColumn = new GridViewTextBoxColumn();
                        _yearColumn.Name = "Year";
                        _yearColumn.HeaderText = "Year";
     
                        _grid.Columns.Add(_yearColumn);
                    }
     
                    // Value Column
                    {
                        _valueColumn = new GridViewTextBoxColumn();
                        _valueColumn.Name = "Value";
                        _valueColumn.HeaderText = "Value";
     
                        _grid.Columns.Add(_valueColumn);
                    }
     
                    // Insert Row Column
                    {
                        _insertRowColumn = new GridViewCommandColumn();
                        _insertRowColumn.Name = "InsertRow";
                        _insertRowColumn.HeaderText = string.Empty;
                        _insertRowColumn.UseDefaultText = true;
                        _insertRowColumn.DefaultText = "+";
                        _insertRowColumn.MinWidth = 20;
                        _insertRowColumn.TextAlignment = ContentAlignment.MiddleCenter;
     
                        _grid.Columns.Add(_insertRowColumn);
                    }
     
                    // Delete Row Column
                    {
                        _deleteRowColumn = new GridViewCommandColumn();
                        _deleteRowColumn.Name = "DeleteRow";
                        _deleteRowColumn.HeaderText = string.Empty;
                        _deleteRowColumn.UseDefaultText = true;
                        _deleteRowColumn.DefaultText = "-";
                        _deleteRowColumn.MinWidth = 20;
                        _deleteRowColumn.TextAlignment = ContentAlignment.MiddleCenter;
     
                        _grid.Columns.Add(_deleteRowColumn);
                    }
                }
     
                // Add Rows
                {
                    for (int i = 1; i <= 5; i++)
                    {
                        GridViewRowInfo row = _grid.Rows.AddNew();
     
                        row.Cells[_yearColumn.Name].Value = i;
                        row.Cells[_valueColumn.Name].Value = i * 10;
                    }
                }
     
                _grid.BestFitColumns();
            }
     
            private void _grid_CommandCellClick(object sender, EventArgs e)
            {
                GridViewCellEventArgs args = e as GridViewCellEventArgs;
     
                if (args.Column == _insertRowColumn)
                {
                    InsertRow(args.RowIndex);
                }
                else if (args.Column == _deleteRowColumn)
                {
                    DeleteRow(args.RowIndex);
                }
            }
     
            private void InsertRow(int aRow)
            {
                GridViewDataRowInfo rowInfo = new GridViewDataRowInfo(_grid.MasterView);
     
                int startYear = Convert.ToInt32(_grid.Rows[aRow].Cells["Year"].Value) + 1;
     
                rowInfo.Cells[_yearColumn.Name].Value = startYear;
                rowInfo.Cells[_valueColumn.Name].Value = startYear * 10;
     
                _grid.Rows.Insert(aRow + 1, rowInfo);
            }
     
            private void DeleteRow(int aRow)
            {
                _grid.Rows.RemoveAt(aRow);
            }
     
            private void _grid_ViewCellFormatting(object sender, CellFormattingEventArgs e)
            {
                if (e.CellElement is GridCommandCellElement && e.RowIndex >= 0)
                {
                    if (e.Column == _insertRowColumn)
                    {
                        if (e.RowIndex + 1 < _grid.RowCount)
                        {
                            int startYear = Convert.ToInt32(_grid.Rows[e.RowIndex].Cells[_yearColumn.Name].Value);
                            int nextYear = Convert.ToInt32(_grid.Rows[e.RowIndex + 1].Cells[_yearColumn.Name].Value);
     
                            if ((startYear + 1) == nextYear)
                            {
                                e.CellElement.Enabled = false;
                            }
                            else
                            {
                                e.CellElement.Enabled = true;
                            }
                        }
                        else
                        {
                            e.CellElement.Enabled = true;
                        }
                    }
                    else if (e.Column == _deleteRowColumn)
                    {
                        if (e.RowIndex == 0)
                        {
                            e.CellElement.Enabled = false;
                        }
                        else
                        {
                            e.CellElement.Enabled = true;
                        }
                    }
                }
            }
        }
    }

    Here is the Designer.cs file:

    namespace GridCellEnabled
    {
        partial class Form1
        {
            /// <summary>
            /// Required designer variable.
            /// </summary>
            private System.ComponentModel.IContainer components = null;
     
            /// <summary>
            /// Clean up any resources being used.
            /// </summary>
            /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
            protected override void Dispose(bool disposing)
            {
                if (disposing && (components != null))
                {
                    components.Dispose();
                }
                base.Dispose(disposing);
            }
     
            #region Windows Form Designer generated code
     
            /// <summary>
            /// Required method for Designer support - do not modify
            /// the contents of this method with the code editor.
            /// </summary>
            private void InitializeComponent()
            {
                this._grid = new Telerik.WinControls.UI.RadGridView();
                ((System.ComponentModel.ISupportInitialize)(this._grid)).BeginInit();
                this.SuspendLayout();
                //
                // _grid
                //
                this._grid.Location = new System.Drawing.Point(12, 12);
                this._grid.Name = "_grid";
                this._grid.Size = new System.Drawing.Size(260, 238);
                this._grid.TabIndex = 0;
                this._grid.ViewCellFormatting += new Telerik.WinControls.UI.CellFormattingEventHandler(this._grid_ViewCellFormatting);
                this._grid.CommandCellClick += new Telerik.WinControls.UI.CommandCellClickEventHandler(this._grid_CommandCellClick);
                //
                // Form1
                //
                this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
                this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
                this.ClientSize = new System.Drawing.Size(284, 262);
                this.Controls.Add(this._grid);
                this.Name = "Form1";
                this.Text = "Form1";
                this.Load += new System.EventHandler(this.Form1_Load);
                ((System.ComponentModel.ISupportInitialize)(this._grid)).EndInit();
                this.ResumeLayout(false);
     
            }
     
            #endregion
     
            private Telerik.WinControls.UI.RadGridView _grid;
        }
    }
  2. Answer
    Ivan Petrov
    Admin
    Ivan Petrov avatar
    705 posts

    Posted 06 Jan 2012 Link to this post

    Hi Troy,

    Thank you for writing and for the provided code.

    I was able to find what was not working properly. When you delete a row, the ViewCellFormatting is fired only for the rows starting from that index to the last visible row, since the rows before the deleted row are unchanged. To force the invalidation of the row above the row you delete you have to explicitly call InvalidateRow. Here is a modified version of your DeleteRow method which does this:
    private void DeleteRow(int aRow)
    {
      _grid.Rows.RemoveAt(aRow);
      if (aRow > 0)
      {
        _grid.Rows[aRow - 1].InvalidateRow();
      }
    }

    I hope this will be useful for you. Should you have further questions I would be glad to help.

    Regards,
    Ivan Petrov
    the Telerik team

    SP1
    of Q3’11 of RadControls for WinForms is available for download (see what's new).
Back to Top