RadGridView added 2 Command Buttons each row want to disable after one is selected on selected row.

2 Answers 235 Views
General Discussions GridView
Roger
Top achievements
Rank 2
Iron
Iron
Iron
Roger asked on 28 Apr 2022, 01:46 PM

I did some searching and finding it difficult to disable button(s) in RadGridView. 

I have a gridview with two buttons (Edit, Delete) then datacolumns in grid.

When Delete is pressed, I want to execute code, disable / hide Edit / Delete buttons on that row only.

I was able to disable the button but then all buttons are now being disabled on all rows.  Even though the buttons are disabled the commandcellClick is still executing when clicking on the disabled button.

I did add the CellFormatting  procedure but it executes so many times it's hard to know what row / cell it's on and when.

 private void gvResults_CellFormatting(object sender, CellFormattingEventArgs e)
        {
                if (e.ColumnIndex == 0)
                   {
                        RadButtonElement b = (RadButtonElement)e.CellElement.Children[0];
                        b.Enabled = false;
                        Debug.Print("Working on cell: " + e.CellElement.Value);
                    }
        }
tar
Top achievements
Rank 2
Iron
Iron
Iron
commented on 28 Apr 2022, 02:38 PM | edited

-

2 Answers, 1 is accepted

Sort by
1
Accepted
tar
Top achievements
Rank 2
Iron
Iron
Iron
answered on 28 Apr 2022, 02:44 PM | edited on 29 Apr 2022, 08:17 PM

If the row remains in the grid after you have pressed the "Delete" button (which I find curious, but anyway), you could/should add a flag property/member to your data entity which you can use as hidden column which is set when you press the "Delete" button.

Then you can check the corresponding flag cell in the Cellformatting event (the ViewCellFormatting event would be even better) and disable the CommandButton if the flag is set.

Here is a fully functioning example:

using System;
using System.Collections.Generic;
using Telerik.WinControls;
using Telerik.WinControls.UI;

namespace GUI {
  public partial class FormTest : RadForm {
    // example entity class
    private class MyEntity {
      public string SomeValue      { get; set; }
      public string SomeOtherValue { get; set; }
      public string State          { get; set; }
      // if you only want to check if the entry is deleted use this instead:
      // public bool   SetForDeletion { get; set; }
    }

    public FormTest() {
      InitializeComponent();
    }

    // add the load event to your form
    private void FormTest_Load(object sender, EventArgs e) {
      InitGV();
    }

    #region === GRIDVIEW ==========================================================================
    #region --- init gridview ---------------------------------------------------------------------
    private void InitGV() {
      // add your columns
      GridViewTextBoxColumn col1 = new GridViewTextBoxColumn();
      col1.FieldName  = "SomeValue";
      col1.Name       = "SomeValue";
      col1.HeaderText = "Some Value";

      GridViewTextBoxColumn col2 = new GridViewTextBoxColumn();
      col2.FieldName  = "SomeOtherValue";
      col2.Name       = "SomeOtherValue";
      col2.HeaderText = "Some Other Value";

      GridViewTextBoxColumn col3 = new GridViewTextBoxColumn();
      col3.FieldName = "State";
      col3.Name      = "State";
      col3.IsVisible = false; // hidden from user

      // if you want to use the boolean flag instead (see MyEntity class above):
      //GridViewCheckBoxColumn col3 = new GridViewCheckBoxColumn();
      //col3.FieldName = "SetForDeletion";
      //col3.Name      = "SetForDeletion";
      //col3.IsVisible = false; // hidden from user

      GridViewCommandColumn col4 = new GridViewCommandColumn();
      col4.FieldName      = "Delete";
      col4.Name           = "Delete";
      col4.HeaderText     = "Delete Entry";
      // if you have an image for the button, set it:
      //col4.Image          = myImageSource;
      //col4.ImageAlignment = System.Drawing.ContentAlignment.MiddleCenter;
      //col4.UseDefaultText = false;

      GridViewCommandColumn col5 = new GridViewCommandColumn();
      col5.FieldName      = "UnDelete";
      col5.Name           = "UnDelete";
      col5.HeaderText     = "UnDelete Entry";

      GridViewCommandColumn col6 = new GridViewCommandColumn();
      col6.FieldName      = "OtherButton";
      col6.Name           = "OtherButton";
      col6.HeaderText     = "Whatever may happen here";

      gv.MasterTemplate.Columns.AddRange(
        col1,
        col2,
        col3,
        col4,
        col5,
        col6
      );

      // load gridview data (example)
      List<MyEntity> entities = new List<MyEntity>() {
        new MyEntity() { SomeValue = "My first entry",  SomeOtherValue = "This is some other value" },
        new MyEntity() { SomeValue = "My second entry", SomeOtherValue = "asdf" },
        new MyEntity() { SomeValue = "My third entry",  SomeOtherValue = "jmfpfa" },
        new MyEntity() { SomeValue = "My fourth entry", SomeOtherValue = "wskjdowjdfßp" },
        new MyEntity() { SomeValue = "My fifth entry",  SomeOtherValue = "ewjwoiedjoi" },
        new MyEntity() { SomeValue = "My sixth entry",  SomeOtherValue = "random stuff" }
      };

      gv.DataSource = entities;

      // clear selection
      gv.ClearSelection();
      gv.CurrentRow = null;

      // wire gridview events
      gv.CommandCellClick   += new CommandCellClickEventHandler(gv_CommandCellClick);
      gv.ViewCellFormatting += new CellFormattingEventHandler(gv_ViewCellFormatting);
    }
    #endregion
    #region --- command cell click ----------------------------------------------------------------
    private void gv_CommandCellClick(object sender, EventArgs e) {
      string columnName = (e as GridViewCellEventArgs).Column.Name;
      MyEntity myEntity = (sender as GridCellElement).RowInfo.DataBoundItem as MyEntity;

      switch (columnName) {
        case "Delete":      Delete(myEntity); break;
        case "UnDelete":    UnDelete(myEntity); break;
        case "OtherButton": SomeOtherFunction(myEntity); break;
      }

      // invalidate the current row to trigger ViewCellFormatting for it
      (e as GridViewCellEventArgs).Row.InvalidateRow();
    }
    #endregion
    #region --- command: delete -------------------------------------------------------------------
    private void Delete(MyEntity myEntity) {
      // do something with your entity
      // ...
      // set its state to deleted
      myEntity.State = "DEL";
      // or the boolean flag:
      // myEntity.SetForDeletion = true;
    }
    #endregion
    #region --- command: undelete -----------------------------------------------------------------
    private void UnDelete(MyEntity myEntity) {
      // reset its state
      myEntity.State = "";
      // or the boolean flag:
      // myEntity.SetForDeletion = false;
    }
    #endregion
    #region --- command: some other function ------------------------------------------------------
    private void SomeOtherFunction(MyEntity myEntity) {
      // do something with your entity
      // ...
    }
    #endregion
    #region --- view cell formatting --------------------------------------------------------------
    private void gv_ViewCellFormatting(object sender, CellFormattingEventArgs e) {
      // add all properties which you change in this formatting method here
      // in order to reset their flags for all non-affected cells
      e.CellElement.ResetValue(LightVisualElement.EnabledProperty, ValueResetFlags.Local);

      // now format the cells to your liking
      if (e.RowIndex == -1) {
        // format header cells: e is GridHeaderCellElement
        // ...

      } else if (e.ColumnIndex > -1) {
        // format data cells: e is GridDataCellElement etc.

        // get the current row item as it is easier to work with
        MyEntity myEntity = e.Row.DataBoundItem as MyEntity;

        if (e.Column.Name == "Delete") { // e.CellElement.ColumnInfo is GridViewCommandColumn
          // enable the delete button depending on the state of the item
          e.CellElement.Enabled = myEntity.State != "DEL";
          // instead of using MyEntity you can also check the corresponding cell value directly:
          // e.CellElement.Enabled = e.Row.Cells["State"].Value != "DEL";
            
          // and when checking the boolean flag:
          // e.CellElement.Enabled = myEntity.SetForDeletion;
          // or the corresponding cell directly:
          // e.CellElement.Enabled = e.Row.Cells["SetForDeletion"].Value;
        }
      }
    }
    #endregion
    #endregion
  }
}

Good luck!
Roger
Top achievements
Rank 2
Iron
Iron
Iron
commented on 28 Apr 2022, 03:00 PM

Am I able to HIDE this column so it is not seen by user?

 

Also even if the commandbutton is disabled, the commandcellClick event is still firing and I am having to now deal with it firing even though the commandbutton is now disabled.

tar
Top achievements
Rank 2
Iron
Iron
Iron
commented on 28 Apr 2022, 03:43 PM | edited

You can set a column visibility when initializing the RadGridView, e.g.:

GridViewTextBoxColumn colState = new GridViewTextBoxColumn();
colState.IsVisible  = false;
gridView.MasterTemplate.Columns.Add(colState);

The CommandCellClick event is not firing here when the button is disabled.

If for whatever reason you cannot solve the firing issue (perhaps you have double events or something else is strange), you could (again) check the "State" column and exit the button function when "DEL" so that nothing happens.

Roger
Top achievements
Rank 2
Iron
Iron
Iron
commented on 28 Apr 2022, 04:08 PM | edited

I do not want the whole column to not be visible as I want that commandbutton to show and work in other rows.

Basically what I am looking for is when the DELETE commandbutton is pressed in Row 5

    I want to perform some action

    I then want that button to not work anymore in Row 5 only.  I am able to disable it, but the commandcellclick is still firing even with the disabled button.

tar
Top achievements
Rank 2
Iron
Iron
Iron
commented on 28 Apr 2022, 04:46 PM | edited

You asked how you could hide a column. This is done by setting IsVisibile to false which you should not use for the button column but for the helper column named "State", e.g.

How you could disable the button for row 5 is explained in my first answer. When your event still fires on row 5 then you did something wrong.

Do you even check for column.Name within the CommandCellClick event in order to distinguish this event when clicking on another column?

tar
Top achievements
Rank 2
Iron
Iron
Iron
commented on 28 Apr 2022, 05:54 PM

I have updated my answer with a fully functioning test form where you can see how it would work.
Roger
Top achievements
Rank 2
Iron
Iron
Iron
commented on 28 Apr 2022, 06:24 PM

Wow, you must be bored.  :-)

 

I am giving it a try now and will update.

Thanks so much.!

 

Roger

Roger
Top achievements
Rank 2
Iron
Iron
Iron
commented on 29 Apr 2022, 12:47 PM

M,

Thanks this did indeed solve my issue.

Great example too for others in the future!

0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 29 Apr 2022, 08:10 AM

Hi, all,

I have reviewed the suggested solution by M. I have also updated your Telerik points for the community efforts. Thank you for your contribution. It is greatly appreciated.

One thing that should be improved is in the CommandCellClick after the delete command is used and the flag is marked as "DEL", invalidate the row in order to disable the command button immediately after clicking. Otherwise, the CellFormatting event wouldn't be fired at once and the button can be clicked once again: 

        private void Delete(MyEntity myEntity)
        {
            // do something with your entity
            // ...
            // set its state to deleted
            myEntity.State = "DEL";
            // or the boolean flag:
            // myEntity.SetForDeletion = true;
            if (this.radGridView1.CurrentRow!=null)
            {
                  this.radGridView1.CurrentRow.InvalidateRow();
            }

        }

I have also prepared a sample project.Please give the sample project a try and see how it works on your end.

Regards,
Dess | Tech Support Engineer, Principal
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

tar
Top achievements
Rank 2
Iron
Iron
Iron
commented on 29 Apr 2022, 08:19 PM

Correct but I would recommend adding it directly to the end of the CommandCellClick event in order that it is triggered on every command and included only once.

I've updated my answer accordingly.

Dess | Tech Support Engineer, Principal
Telerik team
commented on 02 May 2022, 05:48 AM

Yes, it can be added to the end of the CommandCellClick event handler as well.
Tags
General Discussions GridView
Asked by
Roger
Top achievements
Rank 2
Iron
Iron
Iron
Answers by
tar
Top achievements
Rank 2
Iron
Iron
Iron
Dess | Tech Support Engineer, Principal
Telerik team
Share this question
or