Checkboxcolumn in a grid (only one must be checked)

10 posts, 2 answers
  1. Filleau
    Filleau avatar
    114 posts
    Member since:
    Jun 2006

    Posted 29 Apr 2011 Link to this post

    Hi

    I have a RadGrid with 3 columns.

    Column 1 is a GridViewCheckBoxColumns named "ColA"
    Column 2 is a GridViewTextBoxColumn named "ColB"
    Column 3 is a GridViewCheckBoxColumn named "ColC"

    On the third Column only, I want that only one row can be checked.
    So if user click on a CheckBox in Columns 3, all others CheckBox for this column must be unchecked.

    How to do this ?

    Thanks
  2. Emanuel Varga
    Emanuel Varga avatar
    1336 posts
    Member since:
    May 2010

    Posted 29 Apr 2011 Link to this post

    Hello Filleau,

    It's a very rough example but it should do what you want:
    using System.Collections.Generic;
    using System.Linq;
    using System.Windows.Forms;
    using Telerik.WinControls.UI;
     
    public partial class Form1 : Form
    {
        private RadGridView radGridView1;
     
        public Form1()
        {
            InitializeComponent();
            this.Controls.Add(radGridView1 = new RadGridView());
            radGridView1.Dock = DockStyle.Fill;
            radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
     
            var persons = new List<Person>();
            for (int i = 0; i < 10; i++)
            {
                persons.Add(new Person { ID = i, Name = "Person " + i, Active = i % 2 == 0, Representative = false });
            }
     
            radGridView1.DataSource = persons;
            radGridView1.ValueChanging += new ValueChangingEventHandler(radGridView1_ValueChanging);
        }
     
        void radGridView1_ValueChanging(object sender, ValueChangingEventArgs e)
        {
            if (radGridView1.CurrentColumn.FieldName == "Representative")
            {
                foreach (var row in radGridView1.Rows.Where(r =>
                    r.DataBoundItem != null && r.Cells["Representative"].Value != null && (bool)r.Cells["Representative"].Value &&
                    e.NewValue != null && ((bool)e.NewValue) != false))
                {
                    row.Cells["Representative"].Value = false;
                }
            }
        }
    }
     
    public class Person
    {
        public int ID { get; set; }
     
        public string Name { get; set; }
     
        public bool Active { get; set; }
     
        public bool Representative { get; set; }
    }

    Hope this helps, if you have any other questions or comments, please let me know,

    Best Regards,
    Emanuel Varga

    Telerik WinForms MVP
  3. UI for WinForms is Visual Studio 2017 Ready
  4. Filleau
    Filleau avatar
    114 posts
    Member since:
    Jun 2006

    Posted 29 Apr 2011 Link to this post

    Thanks

    But because I'm working with VB, I used the Telerik Converter to try your solution.

    But I have a problem with this line

    radGridView1.ValueChanging +=
    new ValueChangingEventHandler(radGridView1_ValueChanging);

    in VB : radGridView1.ValueChanging += New ValueChangingEventHandler(radGridView1_ValueChanging)


    I don't know where to put it.... Everywhere VS Editor mark it as error

    It's seem I don't have or don't found the Sub NEW()


  5. Emanuel Varga
    Emanuel Varga avatar
    1336 posts
    Member since:
    May 2010

    Posted 29 Apr 2011 Link to this post

    Hello Fileau,

    Those are the AddHandler and RemoveHandler , please change those to this:
    AddHandler radGridView1.ValueChanging, AddressOf radGridView1_ValueChanging

    You should put it in the constructor, or if you prefer to do this from the designer, go to the grid, events, and register for the ValueChanging event from there.

    Hope this helps, if you have any other questions or comments, please let me know,

    Best Regards,
    Emanuel Varga

    Telerik WinForms MVP
  6. Filleau
    Filleau avatar
    114 posts
    Member since:
    Jun 2006

    Posted 29 Apr 2011 Link to this post

    Hey thanks  !

    It was so simple.

    I just resume in :

     

    Private Sub RadGridView1_CellValueChanged(ByVal sender As System.Object, ByVal e As Telerik.WinControls.UI.GridViewCellEventArgs) Handles RadGridView1.CellValueChanged
     If 
    RadGridView1.CurrentColumn.Name = "ColC" Then
      For 
    Each row As GridViewRowInfo In RadGridView1.Rows
         row.Cells("ColC").Value = False
      Next
     End If
    End Sub
  7. Filleau
    Filleau avatar
    114 posts
    Member since:
    Jun 2006

    Posted 01 May 2011 Link to this post

    Hi

    I have one more problem with my code.

    On my grid everything seem to be good. I can have only one checkbox checked.

    But after If I put a RadButton with a code like this :
    For Each row As GridViewRowInfo In RadGridView1.Rows
        If row.Cells("ColC").Value = True Then MsgBox("Hello World !")
     
    Next

    The MsgBox is never Display.
    I have on checkbox checked on the screen but the value is False !

    Thanks
  8. Emanuel Varga
    Emanuel Varga avatar
    1336 posts
    Member since:
    May 2010

    Posted 01 May 2011 Link to this post

    Hello again,

    Try it like this:
    Private Sub button_Click(sender As Object, e As System.EventArgs)
        For Each row As var In Me.radGridView1.Rows
            If row.Cells("Representative").Value IsNot Nothing AndAlso CBool(row.Cells("Representative").Value) Then
                MessageBox.Show("Row " + row.Index + " is checked!")
            End If
        Next
    End Sub

    Hope this helps, if you have any other questions or comments, please let me know,

    Best Regards,
    Emanuel Varga

    Telerik WinForms MVP
  9. Filleau
    Filleau avatar
    114 posts
    Member since:
    Jun 2006

    Posted 02 May 2011 Link to this post

    Sorry but no success with it.

    Private Sub RadGridView1_CellValueChanged(ByVal sender As System.Object
    ByVal e As Telerik.WinControls.UI.GridViewCellEventArgs) Handles 
    RadGridView1.CellValueChanged
      If RadGridView1.CurrentColumn.Name = "Master" Then
          For Each row As GridViewRowInfo In RadGridView1.Rows
                row.Cells("Master").Value = False
          Next
      End If
    End Sub
      
    Private Sub RadButton8_Click(ByVal sender As System.Object, ByVal e As 
    System.EventArgs) Handles RadButton8.Click
      For Each row As GridViewRowInfo In RadGridView1.Rows
           If Not row.Cells("Master").Value Is Nothing AndAlso CBool(row.Cells("Master").Value) Then
              MessageBox.Show("Row " + row.Index + " is checked!")
           End If
      Next
    End Sub


  10. Answer
    Emanuel Varga
    Emanuel Varga avatar
    1336 posts
    Member since:
    May 2010

    Posted 02 May 2011 Link to this post

    Hello again,

    Sorry, i cannot reproduce this problem, but there is one thing that you have changed from my example: The ValueChanging event with the CellValueChanged, basically you are calcelling the selection there, because the ValueChanging event fires before the value has been changed, so I could easily change all of the row's selection state to false, but because you are using the CellValueChanged event you have to ignore the CurrentRow's state.

    Hope you understood, with my suggestion here is a full example:
    Imports System.Collections.Generic
    Imports System.Linq
    Imports System.Windows.Forms
    Imports Telerik.WinControls.UI
     
    Partial Public Class Form1
        Inherits Form
        Private radGridView1 As RadGridView
     
        Public Sub New()
            InitializeComponent()
            Me.Controls.Add(InlineAssignHelper(radGridView1, New RadGridView()))
            radGridView1.Dock = DockStyle.Fill
            radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill
     
            Dim persons = New List(Of Person)()
            For i As Integer = 0 To 9
                persons.Add(New Person() With { _
                 .ID = i, _
                 .Name = "Person " + i.ToString, _
                 .Active = i Mod 2 = 0, _
                 .Representative = False _
                })
            Next
     
            radGridView1.DataSource = persons
            AddHandler radGridView1.ValueChanging, AddressOf radGridView1_ValueChanging
     
            Dim button As New RadButton
            button.Text = "Click me!"
            AddHandler button.Click, AddressOf Button_Click
            button.Dock = DockStyle.Bottom
            Controls.Add(button)
     
        End Sub
     
        Private Sub radGridView1_ValueChanging(ByVal sender As Object, ByVal e As ValueChangingEventArgs)
            If radGridView1.CurrentColumn.FieldName = "Representative" Then
                For Each row As GridViewDataRowInfo In radGridView1.Rows.Where(Function(r) r.DataBoundItem IsNot Nothing AndAlso r.Cells("Representative").Value IsNot Nothing AndAlso CBool(r.Cells("Representative").Value) AndAlso e.NewValue IsNot Nothing AndAlso CBool(e.NewValue) <> False)
                    row.Cells("Representative").Value = False
                Next
            End If
        End Sub
        Private Shared Function InlineAssignHelper(Of T)(ByRef target As T, ByVal value As T) As T
            target = value
            Return value
        End Function
     
        Private Sub Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
            For Each row As GridViewRowInfo In radGridView1.Rows
                If Not row.Cells("Representative").Value Is Nothing AndAlso CBool(row.Cells("Representative").Value) Then
                    MessageBox.Show("Row " + row.Index.ToString + " is checked!")
                End If
            Next
        End Sub
     
     
    End Class
     
    Public Class Person
        Public Property ID() As Integer
            Get
                Return m_ID
            End Get
            Set(ByVal value As Integer)
                m_ID = Value
            End Set
        End Property
        Private m_ID As Integer
     
        Public Property Name() As String
            Get
                Return m_Name
            End Get
            Set(ByVal value As String)
                m_Name = Value
            End Set
        End Property
        Private m_Name As String
     
        Public Property Active() As Boolean
            Get
                Return m_Active
            End Get
            Set(ByVal value As Boolean)
                m_Active = Value
            End Set
        End Property
        Private m_Active As Boolean
     
        Public Property Representative() As Boolean
            Get
                Return m_Representative
            End Get
            Set(ByVal value As Boolean)
                m_Representative = Value
            End Set
        End Property
        Private m_Representative As Boolean
    End Class

    Hope this helps, if you have any other questions or comments, please let me know,

    Best Regards,
    Emanuel Varga

    Telerik WinForms MVP
  11. Answer
    Filleau
    Filleau avatar
    114 posts
    Member since:
    Jun 2006

    Posted 02 May 2011 Link to this post

    This is it !

    Big Thank.


    Private
    Sub RadGridView1_ValueChanging(ByVal sender As System.Object
    ByVal e As Telerik.WinControls.UI.ValueChangingEventArgs) Handles RadGridView1.ValueChanging
    If 
    RadGridView1.CurrentColumn.Name = "Master" And TypeOf (e.NewValue) Is Boolean Then
       For Each row As GridViewDataRowInfo In RadGridView1.Rows
           If (row.Cells("Master").Value IsNot Nothing AndAlso CBool(row.Cells("Master").Value) AndAlso e.NewValue IsNot Nothing AndAlso CBool(e.NewValue) <> FalseThen
          
        
    row.Cells("Master").Value = False
           End If
         Next
       End If
    End Sub


    I made some minors changes because at the beginning I have some problem with your converter result, and also, but I don't know why sometime I got a exeption because a string value (from another column !)... That's why I test typeof(e.newValue)
Back to Top
UI for WinForms is Visual Studio 2017 Ready