GridView, How do I change a cell's value based on a change in another cell?

1 Answer 133 Views
GridView
Michael
Top achievements
Rank 1
Iron
Iron
Veteran
Michael asked on 04 Aug 2023, 11:41 AM

I have a combobox column that shows an Enum value and a second column, a text column, that shows descriptive text about the Enum.

This is a bound grid and the Enum is a property in the bound object while the descriptive text is a computed property.

When I select a value from the combobox, I want the descriptive text column to change immediately - without having to wait 'til the user leaves the combobox cell.

Using the ValueChanged event I can catch the combobox change immediately, but I haven't been able to show the change in the text column.  The property in the DataBoundItem hasn't changed yet, and even if it had I don't know that the text column would refresh automatically.  I've tried setting the text value, but it doesn't work.  I've tried calling Refresh() and EndEdit() -- also nothing.

I can't be the only one doing this.  How's it done?

Thanks in advance.

tar
Top achievements
Rank 2
Iron
Iron
Iron
commented on 05 Aug 2023, 06:53 AM

Bound data should immediately update the GridView. Otherwise you would need to use InvalidateRow() with the corresponding RowIndex of the entry in the GridView.
Michael
Top achievements
Rank 1
Iron
Iron
Veteran
commented on 05 Aug 2023, 07:44 PM

Thanks, @tar, but the bound property doesn't get updated until the user leaves the cell.  I can call EndEdit(), which I assume will update the property, but that doesn't cause the other cell to update.  It could be that if I call EndEdit() and then InvalidateRow() it'll work, and I'll try that, but I prefer to not call EndEdit(), as that actually changes the user experience.

1 Answer, 1 is accepted

Sort by
0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 08 Aug 2023, 08:58 AM

Hi, Michael,

Following the provided information, I have prepared a sample code snippet that covers the described scenario. The achieved result is illustrated in the gif file.

        Dictionary<int,string> statuses= new Dictionary<int,string>();
        public RadForm1()
        {
            InitializeComponent();
            statuses.Add(1, "A new item that needs to be reviewed and triaged by the team.");
            statuses.Add(2, "The team is currently working on this item.");
            statuses.Add(3, "Implemented. Refer to the item for information about the release this is included in.");

            DataTable dt = new DataTable();
            dt.Columns.Add("Id", typeof(int));
            dt.Columns.Add("Name", typeof(string));
            dt.Rows.Add(1, "Pending Review");
            dt.Rows.Add(2, "In Development");
            dt.Rows.Add(3, "Completed");

            GridViewComboBoxColumn comboColumn = new GridViewComboBoxColumn("Status"); 
            comboColumn.DataSource = dt;
            comboColumn.ValueMember = "Id";
            comboColumn.DisplayMember = "Name"; 
            comboColumn.Width = 200;
            this.radGridView1.Columns.Add(comboColumn);

            GridViewTextBoxColumn descriptionColumn = new GridViewTextBoxColumn("Description");
            this.radGridView1.Columns.Add(descriptionColumn);
            this.radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;

            this.radGridView1.CellEditorInitialized += RadGridView1_CellEditorInitialized;

            BindingList<Item> items = new BindingList<Item>();
            items.Add(new Item(2, statuses[2])); ;
        }

        private void RadGridView1_CellEditorInitialized(object sender, GridViewCellEventArgs e)
        {
            RadDropDownListEditor editor = e.ActiveEditor as RadDropDownListEditor;
            if (editor != null)
            {
                RadDropDownListEditorElement el = editor.EditorElement as RadDropDownListEditorElement;
                el.SelectedValueChanged -= El_SelectedValueChanged;
                el.SelectedValueChanged += El_SelectedValueChanged;
            }
        }

        private void El_SelectedValueChanged(object sender, Telerik.WinControls.UI.Data.ValueChangedEventArgs e)
        {
            if (e.NewValue!=null)
            {
                int id = (int)e.NewValue;
                if (statuses.ContainsKey(id))
                {
                    this.radGridView1.CurrentRow.Cells["Description"].Value = statuses[id];
                }
            }
        }

        public class Item : System.ComponentModel.INotifyPropertyChanged
        {
            int s_id;
            string m_name; 
            public event PropertyChangedEventHandler PropertyChanged;
            public Item(int s_id, string m_description)
            {
                this.s_id = s_id;
                this.m_name = m_description;
                 
            }
            public int Id
            {
                get
                {
                    return s_id;
                }
                set
                {
                    if (this.s_id != value)
                    {
                        this.s_id = value;
                        OnPropertyChanged("Id");
                    }
                }
            }
            public string Name
            {
                get
                {
                    return m_name;
                }
                set
                {
                    if (this.m_name != value)
                    {
                        this.m_name = value;
                        OnPropertyChanged("Name");
                    }
                }
            }
          
            protected virtual void OnPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
        }

I hope this information helps. If you need any further assistance please don't hesitate to contact me. 

Regards,
Dess | Tech Support Engineer, Principal
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Michael
Top achievements
Rank 1
Iron
Iron
Veteran
commented on 19 Feb 2024, 07:56 PM

I finally got back to this.  My adaptation of the code you provided to my specific circumstances did not quite work.  The value of the target cell was changed, and changed correctly, but the change didn't appear.  In the end I added a 
CellValueChanged handler that called e.Row.InvalidateRow() and that did the trick.
Dess | Tech Support Engineer, Principal
Telerik team
commented on 20 Feb 2024, 05:32 AM

Hi, Michael,

RadGridView is capable of fetching bindable properties and data. However, one important issue must be noted: during the data binding process, the grid extracts the data from the data source, but for any later changes in the data source, RadGridView should be notified. Your bindable collection and business objects should follow some standards established in .NET in order to notify RadGridView about the changes: Reflecting Custom Object Changes in RGV

Tags
GridView
Asked by
Michael
Top achievements
Rank 1
Iron
Iron
Veteran
Answers by
Dess | Tech Support Engineer, Principal
Telerik team
Share this question
or