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

Set cell state in GridViewCheckboxColumn programatically and update binding source

1 Answer 278 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Vadim
Top achievements
Rank 1
Veteran
Vadim asked on 08 Jun 2020, 07:46 AM

I'm making a custom behavior for Telerik's RadGridView.
When this behavior is attached and its `PropertyName` is set to same property as specified by
DataMemberBinding value of some of the GridViewCheckBoxColumn of the grid, then toggling the checkbox in that column will apply same checkbox state to all selected rows (but only to the same column).  

That happens in the `ApplyToAllSelected` method, namely in `gvcb.SetCurrentValue(GridViewCheckBox.IsCheckedProperty, isChecked);` line. The visuals are working as expected, and all checkbox values are updated on screen.

**The Problem** is that the binding source is not updated for those rows. Only for the one where click happened. `GridViewCheckBox.IsChecked` dependency property does not seem to be bound directly to the datacontext's property, so `gvcb.GetBindingExpression(GridViewCheckBox.IsChecked)` returns `null`.

**The Question**: how to update source after setting checkbox state?


```
public sealed class CheckAllSelectedBehavior : Behavior<RadGridView>
    {
        public event EventHandler Toggled;

        public string PropertyName { get; set; }

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

            this.AssociatedObject.PreparingCellForEdit += this.AssociatedObject_PreparedCellForEdit;
            this.AssociatedObject.CellEditEnded += this.AssociatedObject_CellEditEnded;
        }

        protected override void OnDetaching()
        {
            this.AssociatedObject.PreparingCellForEdit -= this.AssociatedObject_PreparedCellForEdit;
            this.AssociatedObject.CellEditEnded -= this.AssociatedObject_CellEditEnded;
            base.OnDetaching();
        }

        private void AssociatedObject_CellEditEnded(object sender, GridViewCellEditEndedEventArgs e)
        {
            if (e.Cell.Column.UniqueName == this.PropertyName && e.EditingElement is CheckBox cb)
            {
                cb.Checked -= this.Cb_Checked;
                cb.Unchecked -= this.Cb_Unchecked;
            }
        }

        private void AssociatedObject_PreparedCellForEdit(object sender, GridViewPreparingCellForEditEventArgs e)
        {
            if (e.Column.UniqueName == this.PropertyName && e.EditingElement is CheckBox cb)
            {
                cb.Checked += this.Cb_Checked;
                cb.Unchecked += this.Cb_Unchecked;
            }
        }

        private void Cb_Unchecked(object sender, System.Windows.RoutedEventArgs e)
        {
            this.ApplyToAllSelected(false);
        }

        private void Cb_Checked(object sender, System.Windows.RoutedEventArgs e)
        {
            this.ApplyToAllSelected(true);
        }

        private void ApplyToAllSelected(bool isChecked)
        {
            foreach (var item in this.AssociatedObject.SelectedItems)
            {
                var row = this.AssociatedObject.GetRowForItem(item);
                var cell = row.GetCellFromPropertyName(this.PropertyName);
                if (cell.Content is GridViewCheckBox gvcb)
                {
                    gvcb.SetCurrentValue(GridViewCheckBox.IsCheckedProperty, isChecked);
                }
            }

            this.Toggled?.Invoke(this, EventArgs.Empty);
        }
    }
```

This is a copy of [StackOverflow Thread](https://stackoverflow.com/questions/62192784/programatically-change-state-of-gridviewcheckboxcolumn-row-with-updating-binding)

1 Answer, 1 is accepted

Sort by
0
Petar Mladenov
Telerik team
answered on 11 Jun 2020, 05:59 AM

Hi Vadim,

I can see multiple issues with similar approach. One is that you work with visual elements in code, but it seems to me it can be achieved with work over viewmodels / models (issue of coupling UI with models). Other issues is that when the GridView is virtualized and has many rows, you won't be able to get the row for a specific model because it may not be generated in the current viewport. So my general advice is to try to convert your solution to iterate and work with models. Also if there is a binding issue with the CheckBoxColumn, you can try using GridViewDataColumn, add CheckBox in its CellTemplate and add two-way binding which will be directly binding the checkbox to the ViewModel value.

Regards,
Petar Mladenov
Progress Telerik

Progress is here for your business, like always. Read more about the measures we are taking to ensure business continuity and help fight the COVID-19 pandemic.
Our thoughts here at Progress are with those affected by the outbreak.
Tags
GridView
Asked by
Vadim
Top achievements
Rank 1
Veteran
Answers by
Petar Mladenov
Telerik team
Share this question
or