CheckBox selection column in a RadGridView

9 posts, 0 answers
  1. Alexandru
    Alexandru avatar
    4 posts
    Member since:
    Apr 2012

    Posted 15 Dec 2014 Link to this post

    hi,

    in a winforms app, i am using a RadGridView with MultiSelect = true and i am trying to create a column with check-boxes that will be checked for each row that is selected.
    i want this column to work in both ways:
      1) the check-boxes should update themselves each time the list of selected rows is changed.
      2) the user should be able to select additional rows by checking the check-boxes in this column.

    currently i was able to implement the first request (the check-boxes are updating themselves according to the selected rows), but not the second one.

    i subscribed to the SelectionChanged event of the grid, i unchecked the previously selected check-boxes and then checked the ones from the currently selected rows. here is the code:


            private readonly List<GridViewRowInfo> previouslySelectedRows = new List<GridViewRowInfo>();

            private void HandleGridSelectionChanged(object sender, EventArgs e)
            {
                    UnCheckPreviouslySelectedRows();
                    CheckCurrentlySelectedRows();
                    StoreCurrentlySelectedRows();
            }

            private void UnCheckPreviouslySelectedRows()
            {
                foreach (GridViewRowInfo row in previouslySelectedRows)
                {
                    row.Cells["Select"].Value = false;
                }
            }

            private void CheckCurrentlySelectedRows()
            {
                IEnumerable<GridViewCellInfo> cells = radGridView1.SelectedRows
                    .Select(x => x.Cells["Select"]);

                foreach (GridViewCellInfo cell in cells)
                {
                    cell.Value = true;
                }
            }

            private void StoreCurrentlySelectedRows()
            {
                previouslySelectedRows.Clear();
                previouslySelectedRows.AddRange(radGridView1.SelectedRows);
            }

    did someone implement something similar?
    can someone help me with the second task (to let the user select/unselect rows by checking/unchecking the check-boxes)?

    thank you,
    alez

  2. Hristo
    Admin
    Hristo avatar
    714 posts

    Posted 17 Dec 2014 Link to this post

    Hello Alexandru,

    Thank you for writing.

    The code you provided appears to be working properly. If you would like to keep your logic and additionally allow the user to select rows by simply changing the checkbox value you should also subscribe to CellBeginEdit event. Then you should cancel it because letting it to execute would interfere with you logic:
    private void radGridView1_CellBeginEdit(object sender, GridViewCellCancelEventArgs e)
    {
        if (this.radGridView1.CurrentColumn.Name == "Select")
        {
            e.Cancel = true;
        }
    }

    Please bear in mind that multiple selection by design works by holding the Ctrl key. I have attached a .gif file demonstrating the behavior of the grid on my side.

    Hope this helps. Should you have further questions do not hesitate to write back.

    Regards,
    Hristo
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
  3. UI for WinForms is Visual Studio 2017 Ready
  4. Srividya
    Srividya avatar
    2 posts
    Member since:
    Mar 2016

    Posted 07 Oct Link to this post

    Hi Team,

    I have different case in the multi level grid view.

    Parent 1

      Child 1

        Child 1-1

        Child 1-2

        Child 1-3

      Child 2

        Child 2-1

         Child 2-2

    Parent 2

    ect....

    in above multi level grid check box is placed at the last column

    My scenario:

    1. if we check the parent 1->Child 1  then all corresponding child (child 1-1,child 1-2)check boxes should be checked.

    2. if we uncheck the child 1-1 then child 1 should be uncheck as well as child 1-2 should be in previous state because we haven't touch it ;)

    3. if we select a new row I mean parent 2-> child 1-1 then should work above 2 scenarios

    4.if we uncheck and check the same row the above first 2 scenarios should work

     

    Please help me out with a simple solution I tried with so many ways by keeping Boolean variables in the code..but no use of it

  5. Hristo
    Admin
    Hristo avatar
    714 posts

    Posted 07 Oct Link to this post

    Hi Srividya,

    Thank you for writing.

    You can achieve this task by iterating the hierarchy and data rows for the different hierarchy templates: Iterating the child rows collection of a chosen parent row in hierarchy RadGridView.

    A suitable place for performing this operation is the handler of the CellValueChanged event. Please check my code snippet below: 
    bool suspendEvent = false;
    private void radGridView1_CellValueChanged(object sender, GridViewCellEventArgs e)
    {
        if (!suspendEvent && e.Column.Name == "IsValid")
        {
            List<GridViewHierarchyRowInfo> parents = new List<GridViewHierarchyRowInfo>();
            GridViewHierarchyRowInfo parent = e.Row.Parent as GridViewHierarchyRowInfo;
            while (parent != null)
            {
                parents.Add(parent);
                parent = parent.Parent as GridViewHierarchyRowInfo;
            }
     
            suspendEvent = true;
            foreach (GridViewHierarchyRowInfo p in parents)
            {
                if (p.Views.Count > 0)
                {
                    p.Cells["IsValid"].Value = this.CheckCellsForLevel(p.Views[0]);
                }
            }
     
            GridViewHierarchyRowInfo hierarchyRow = e.Row as GridViewHierarchyRowInfo;
            if (hierarchyRow != null)
            {
                Queue<GridViewHierarchyRowInfo> children = new Queue<GridViewHierarchyRowInfo>();
                children.Enqueue(hierarchyRow);
     
                while (children.Count > 0)
                {
                    GridViewHierarchyRowInfo current = children.Dequeue();
                    foreach (GridViewRowInfo row in current.ChildRows)
                    {
                        row.Cells["IsValid"].Value = e.Value;
                        if (row is GridViewHierarchyRowInfo)
                        {
                            children.Enqueue((GridViewHierarchyRowInfo)row);
                        }
                    }
                }
            }
     
            suspendEvent = false;
        }
    }
     
    private bool CheckCellsForLevel(GridViewInfo template)
    {
        foreach (GridViewRowInfo rowInfo in template.Rows)
        {
            if ((bool)rowInfo.Cells["IsValid"].Value == false)
            {
                return false;
            }
        }
     
        return true;
    }

    Please note that in order to illustrate the idea and to make the example simpler in all of my grid templates I am having a GridViewCheckBoxColumn with the name IsValid. You may need to alter this to access the proper cells in your actual project. I am also sending you a short video showing the result on my end.

    I hope this helps. Should you have further questions please do not hesitate to write back.

    Regards,
    Hristo Merdjanov
    Telerik by Progress
    Check out the Windows Forms project converter, which aids the conversion process from standard Windows Forms applications written in C# or VB to Telerik UI for WinForms. For more information check out this blog post and share your thoughts.
  6. Srividya
    Srividya avatar
    2 posts
    Member since:
    Mar 2016

    Posted 10 Oct in reply to Hristo Link to this post

    Hi Hristo,

    The above code is working as expected thank you so much.....

    :)

    Regards,

    Srividya

  7. swarupa
    swarupa avatar
    11 posts
    Member since:
    Aug 2016

    Posted 10 Oct Link to this post

    Hi Hristo,

    The above code is useful for one of my requirements.

    I am using telerik 2013 version.

    I need to display Checkbox in the header row for all the three level gridview, so that I can check and uncheck the checkboxes in the data rows automatically when the header checkbox is checked or unchecked.

    In 2013 version we don't have Gridviewcheckboxcolumn.EnableHeaderCheckBox Property.

    So I have used the following code, which I have taken from Telerik forums to enable the header check boxes in all the

    three levels gridview. Its working fine in the first level gridview, but it is not working for second and third levels gridview.

     

    public class CheckBoxHeaderCell : GridHeaderCellElement
    {
    #region Fields
    private RadCheckBoxElement checkbox;
    private int suspendNotificationCount = 0;
    private bool suspendProcessingToggleStateChanged;
    #endregion
    #region Initialization
    public CheckBoxHeaderCell(GridViewColumn column, GridRowElement row)
    : base(column, row)
    {
    }
    protected override void InitializeFields()
    {
    base.InitializeFields();
    this.DrawText = false;
    }
    public override void Initialize(GridViewColumn column, GridRowElement row)
    {
    base.Initialize(column, row);
    column.AllowSort = false;
    }
    protected override void DisposeManagedResources()
    {
    this.checkbox.ToggleStateChanged -= new StateChangedEventHandler(checkbox_ToggleStateChanged);
    base.DisposeManagedResources();
    }
    protected override void CreateChildElements()
    {
    base.CreateChildElements();
    this.checkbox = new RadCheckBoxElement();
    this.checkbox.ToggleStateChanged += new StateChangedEventHandler(checkbox_ToggleStateChanged);
    this.Children.Add(checkbox);
    } #endregion
    #region Properties
    protected override Type ThemeEffectiveType
    {
    get
    {
    return typeof(GridHeaderCellElement);
    }
    }
    public override object Value
    {
    get
    {
    return Convert.ToBoolean(this.RowInfo.Tag);
    }
    set
    {
    this.RowInfo.Tag = value;
    }
    } #endregion
    #region Methods
    public void SetCheckBoxState(Telerik.WinControls.Enumerations.ToggleState state)
    {
    suspendProcessingToggleStateChanged = true;
    this.checkbox.ToggleState = state;
    suspendProcessingToggleStateChanged = false;
    }

    protected override void SetContentCore(object value)
    {
    base.SetContentCore(value);
    this.suspendNotificationCount++;
    if (this.RowInfo.Tag != null)
    {
    this.checkbox.ToggleState = (bool)value ? ToggleState.On : ToggleState.Off;
    }
    else
    {
    this.checkbox.ToggleState = ToggleState.Off;
    }
    this.checkbox.TextElement.Text = this.Text;
    this.suspendNotificationCount--;
    }
    public override bool IsCompatible(GridViewColumn data, object context)
    {
    return data.Name == "Select" && context is GridTableHeaderRowElement
    && base.IsCompatible(data, context);
    }
    #endregion
    #region Event Handlers
    private void checkbox_ToggleStateChanged(object sender, StateChangedEventArgs args)
    {
    if (!suspendProcessingToggleStateChanged)
    {
    for (int i = 0; i < this.GridControl.Rows.Count; i++)
    {
    this.GridControl.Rows[i].Cells[this.ColumnIndex].Value = this.checkbox.IsChecked;
    }
    }

    } #endregion
    #region Layout
    protected override SizeF ArrangeOverride(SizeF finalSize)
    {
    SizeF size = base.ArrangeOverride(finalSize);
    RectangleF rect = GetClientRectangle(finalSize);
    this.checkbox.Arrange(new RectangleF((finalSize.Width - this.checkbox.DesiredSize.Width) / 2, (rect.Height - 20) / 2, 20, 20));
    return size;
    } #endregion }

    private void DgSearchBdPortsResult_CreateCell(object sender, Telerik.WinControls.UI.GridViewCreateCellEventArgs e)
    {
    if (e.Row is GridTableHeaderRowElement && e.Column.HeaderText == "Select All")
    {
    e.CellElement = new CheckBoxHeaderCell(e.Column, e.Row);
    }

    }

     

    private void DgSearchBdPortsResult_ValueChanged(object sender, EventArgs e)
    {
    DgSearchBdPortsResult.EndEdit();

    }

    Thanks And Regards,

    Swarupa

     

  8. Hristo
    Admin
    Hristo avatar
    714 posts

    Posted 10 Oct Link to this post

    Hello Swarupa,

    Thank you for writing back.

    I am glad that the suggested approach is working well in your project. Regarding the header checkbox please note that the KB solution as stated here and our latter implementation handles the rows from a single template.

    When you have the grid created in a hierarchy the columns on the various levels may be completely different. If you want this header checkbox to be responsible for rows located in child templates you need to handle it separately. You can alter the solution from the KB article to cope with the hierarchy following an approach as the one discussed here.

    I hope this helps. Should you have further questions please do not hesitate to write back.

    Regards,
    Hristo Merdjanov
    Telerik by Progress
    Check out the Windows Forms project converter, which aids the conversion process from standard Windows Forms applications written in C# or VB to Telerik UI for WinForms. For more information check out this blog post and share your thoughts.
  9. Pavel
    Pavel avatar
    22 posts
    Member since:
    Sep 2016

    Posted 19 Oct Link to this post

    Sorry for bumping an old thread, but this is the exact same thing I am trying to do.

    I tried subscribing to the CellBeginEdit event, but as soon as I click the checkbox, all the rows get deselected. What are the ppoperties that my RadGrid and my columns need to have in order to make it work?

  10. Hristo
    Admin
    Hristo avatar
    714 posts

    Posted 20 Oct Link to this post

    Hi Pavel,

    Thank you for writing.

    I am not sure what exactly is your scenario. Can you please provide more details about your task. A general code snippet demonstrating your local setup would also help.

    Looking forward to your reply.

    Regards,
    Hristo Merdjanov
    Telerik by Progress
    Check out the Windows Forms project converter, which aids the conversion process from standard Windows Forms applications written in C# or VB to Telerik UI for WinForms. For more information check out this blog post and share your thoughts.
Back to Top
UI for WinForms is Visual Studio 2017 Ready