GridViewSelectColumn checkbox header checked state.

4 posts, 0 answers
  1. Chun
    Chun avatar
    2 posts
    Member since:
    Mar 2012

    Posted 20 Mar 2012 Link to this post

    Hi,
      I am using a RadGridView to show my items and it contains a GridViewSelectColumn.  I do not want every item to be selectable (defined by a property within the item) so I listen to the SelectionChanging event of the RadGridView and cancel the SelectionChanging if an unselectable item is clicked.

    Simiarly, I have override the GridViewSelectColumn's header with my own checkbox and listens to the Checkbox's click event to handle selecting only the items that are selectable when the header checkbox is clicked.  I also adding a listener to the RadGridView's SelectionChanged event and check that if all selectable items are selected, then I set the header checkbox's IsChecked to true.

    Here's the problem I am having.  The header checkbox does not appear as checked when I click on it even though all selectable items are checked.  Similarly, when I check all the selectable items one by one, when all items are checked the header checkbox does not appear as checked.

    I have read that the checkbox may not appear as expected  due to virtualization by default.  Is there any way around this? 
    Is there a way to bind my DataItems (and the property I use as condition) with the state of the GridViewSelectColumn's header checkbox?

    Thanks!
    Chun  

  2. Maya
    Admin
    Maya avatar
    4062 posts

    Posted 21 Mar 2012 Link to this post

    Hi Chun,

    The virtualization will interfere if you set  IsChecked properties of the CheckBox-es in the row for example and start scrolling. Then the visual elements will be recycled and reused and the IsChecked value might be cleared. However, if you set IsChecked property of the header's CheckBox this will probably not be the reset due to the virtualization. Nevertheless, thee recommended approach is always to update underlying properties of the items instead of working with the visual elements.
    Could you share a bit more details about your exact implementation ? Generally, providing any additional relevant code-snippet and information would great. Also, could you take a look at the sample attached in this forum thread as it might be helpful for you ? 

    Greetings,
    Maya
    the Telerik team
    Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
  3. Chun
    Chun avatar
    2 posts
    Member since:
    Mar 2012

    Posted 21 Mar 2012 Link to this post

    Hi Maya,
      Thanks for the response!  Here are some code snippets. 


    <telerik:RadGridView x:Name="SelectionGrid" Grid.Row="1" IsReadOnly="True" SelectionChanging="OnSelectionChanging" SelectionChanged="OnSelectionChanged">
        <telerik:RadGridView.Columns>
            <vpagecontrols:CustomGridViewSelectColumn">
                <telerik:GridViewSelectColumn.Header>
                    <CheckBox Click="OnSelectionColumnHeaderClicked">
                    </CheckBox>
                </telerik:GridViewSelectColumn.Header>
            </vpagecontrols:CustomGridViewSelectColumn>
            <!--some other columns here-->
        </telerik:RadGridView.Columns>
    </telerik:RadGridView>

    I defined my other Custom GridViewSelectColumn because I want to make a checkbox in a row disabled and appear opaque to disallow users from clicking it.

    public class CustomGridViewSelectColumn : GridViewSelectColumn
    {
        public override FrameworkElement CreateCellElement(GridViewCell cell, object dataItem)
        {
            var element = base.CreateCellElement(cell, dataItem);
     
            var checkBox = element as CheckBox;
            if (checkBox != null)
            {
                checkBox.SetBinding(CheckBox.OpacityProperty, new Binding() { Source = dataItem, Converter = new SignDocumentOpacityConverter(), ConverterParameter="0.75", Mode = BindingMode.OneWay });
                checkBox.SetBinding(CheckBox.IsEnabledProperty, new Binding() { Source = dataItem, Converter = new SignDocumentEnabledConverter() , Mode = BindingMode.OneWay });
            }
     
            return element;
        }
    }

    I also listen to the grid's SelectionChanging and SelectionChanged events.  In SelectionChanging, it will cancel and handle the event if user selects a row that is not supposed to be selectable.  In SelectionChanged, it checks to see if all selectable items are selected.  If so, it sets the column header checkbox to checked.

    private void OnSelectionChanging(object sender, Telerik.Windows.Controls.SelectionChangingEventArgs args)
    {
            foreach (var item in args.AddedItems)
            {
                if (!((MyObject)item).IsSelectable)
                {
                    args.Cancel = true;
                    args.Handled = true;
                    return;
                }
            }
        }
    }
     
    private void OnSelectionChanged(object sender, Telerik.Windows.Controls.SelectionChangeEventArgs args)
    {
        // if all selectable items are selected, then make the column header's checkbox checked.
        bool isChecked = AreAllItemsSelected(); 
        selectionColumnHeaderCheckBox.IsChecked = isChecked;
    }

    Finally, I override the GridViewSelectColumn's header will my own checkbox, and listens to the OnClick event.  It checks the column header's checkbox's IsChecked property and either selects or unselects the items within the grid.
    private void OnSelectionColumnHeaderClicked(object sender, RoutedEventArgs args)
    {
        CheckBox headerCheckBox = sender as CheckBox;
      
        if (headerCheckBox.IsChecked == true)
        {
            SelectAllItems();
        }
        else if (headerCheckBox.IsChecked == false)
        {
            this.SelectionGrid.UnselectAll();
        }
    }
     
    private void SelectAllItems()
    {
        ObservableCollection<MyObject> newSelectedItems = new ObservableCollection<MyObject>();
         foreach (var item in this.SelectionGrid.Items)
         {
             MyObject obj = item as MyObject;
              if (obj.IsSelectable)
              {
                   newSelectedItems.Add(obj);
              }
         }
         this.SelectionGrid.Select(newSelectedItems);
    }

    With this code it seems that checking each individual checkbox in a row, multi-selecting, etc, all seems to be fine.  It is just that when clicking on the header checkbox, on the first click, all selectable rows will be selected but the header checkbox will be shown as unchecked.  On the second click the header checkbox will be shown as checked and all selectable items are remained checked (which is good).  The problem is that I would expect this to happen on the first click, not on the second click.  On the third click it will uncheck all checkboxes (header included) which is the intended behavior. 

    I would like to keep using GridViewSelectColumn instead of GridViewCheckBoxColumn since it gives me the nice property of checking the checkbox when selecting anywhere in the row.  However, if there is a way to achieve this easily with GridViewCheckBoxColumn I am certainly happy to use it as well.
     
    Thank you again and any help would be appreciated.  Let me know shall you need more info!
    Chun
  4. Maya
    Admin
    Maya avatar
    4062 posts

    Posted 26 Mar 2012 Link to this post

    Hello Chun,

    I have managed to reproduce the issue you reported with the provided code-snippets. I will investigate the case and let you know once I could provide more information on the topic.

     

    Greetings,
    Maya
    the Telerik team
    Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
Back to Top