Add "Check All" in the header cell for a GridViewCheckBoxColumn
Product Version | Product | Author | Last modified |
---|---|---|---|
Q2 2013 | RadGridView for WinForms | Martin Vassilev | August 14, 2013 |
HOW TO
Add a check box element in the header cell for GridViewCheckBoxColumn. Implement check/uncheck functionality.
In the latest Telerik versions GridViewCheckBoxColumn offers EnableHeaderCheckBox property out of the box.
DESCRIPTION
It is a very common scenario to use an check box column in RadGridView that allows to end user to mark RadGridView's rows for some operations. It is a valuable feature to have a "check/uncheck all" functionality integrated in the header.
SOLUTION In order to get the desired functionality, you can create and use a custom header cell. Add a check box element in the custom cell and implement ToggleStateChanged and the ValueChanged event. Then, create a column which uses the custom header cell.
public class CheckBoxHeaderCell : GridHeaderCellElement
{
RadCheckBoxElement checkbox;
protected override Type ThemeEffectiveType
{
get
{
return typeof(GridHeaderCellElement);
}
}
public CheckBoxHeaderCell(GridViewColumn column, GridRowElement row)
: base(column, row)
{
}
public override void Initialize(GridViewColumn column, GridRowElement row)
{
base.Initialize(column, row);
column.AllowSort = false;
}
public override void SetContent()
{
}
protected override void DisposeManagedResources()
{
checkbox.ToggleStateChanged -= new StateChangedEventHandler(checkbox_ToggleStateChanged);
base.DisposeManagedResources();
}
protected override void CreateChildElements()
{
base.CreateChildElements();
checkbox = new RadCheckBoxElement();
checkbox.ToggleStateChanged += new StateChangedEventHandler(checkbox_ToggleStateChanged);
this.Children.Add(checkbox);
}
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;
}
public override bool IsCompatible(GridViewColumn data, object context)
{
return data.Name == "Select" && context is GridTableHeaderRowElement
&& base.IsCompatible(data, context);
}
private void checkbox_ToggleStateChanged(object sender, StateChangedEventArgs args)
{
if (!suspendProcessingToggleStateChanged)
{
bool valueState = false;
if (args.ToggleState == Telerik.WinControls.Enumerations.ToggleState.On)
{
valueState = true;
}
this.GridViewElement.EditorManager.EndEdit();
this.TableElement.BeginUpdate();
for (int i = 0; i < this.ViewInfo.Rows.Count; i++)
{
this.ViewInfo.Rows[i].Cells[this.ColumnIndex].Value = valueState;
}
this.TableElement.EndUpdate(false);
this.TableElement.Update(GridUINotifyAction.DataChanged);
}
}
private bool suspendProcessingToggleStateChanged;
public void SetCheckBoxState(Telerik.WinControls.Enumerations.ToggleState state)
{
suspendProcessingToggleStateChanged = true;
this.checkbox.ToggleState = state;
suspendProcessingToggleStateChanged = false;
}
public override void Attach(GridViewColumn data, object context)
{
base.Attach(data, context);
this.GridControl.ValueChanged += new EventHandler(GridControl_ValueChanged);
}
public override void Detach()
{
if (this.GridControl != null)
{
this.GridControl.ValueChanged -= GridControl_ValueChanged;
}
base.Detach();
}
void GridControl_ValueChanged(object sender, EventArgs e)
{
RadCheckBoxEditor editor = sender as RadCheckBoxEditor;
if (editor != null)
{
this.GridViewElement.EditorManager.EndEdit();
if ((ToggleState)editor.Value == ToggleState.Off)
{
SetCheckBoxState(ToggleState.Off);
}
else if ((ToggleState)editor.Value == ToggleState.On)
{
bool found = false;
foreach (GridViewRowInfo row in this.ViewInfo.Rows)
{
if (row != this.RowInfo && row.Cells[this.ColumnIndex].Value == null || !(bool)row.Cells[this.ColumnIndex].Value)
{
found = true;
break;
}
}
if (!found)
{
SetCheckBoxState(ToggleState.On);
}
}
}
}
}
Public Class CheckBoxHeaderCell
Inherits GridHeaderCellElement
Private checkbox As RadCheckBoxElement
Protected Overrides ReadOnly Property ThemeEffectiveType() As Type
Get
Return GetType(GridHeaderCellElement)
End Get
End Property
Public Sub New(ByVal column As GridViewColumn, ByVal row As GridRowElement)
MyBase.New(column, row)
End Sub
Public Overrides Sub Initialize(ByVal column As GridViewColumn, ByVal row As GridRowElement)
MyBase.Initialize(column, row)
column.AllowSort = False
End Sub
Public Overloads Overrides Sub SetContent()
End Sub
Protected Overrides Sub DisposeManagedResources()
RemoveHandler checkbox.ToggleStateChanged, AddressOf checkbox_ToggleStateChanged
MyBase.DisposeManagedResources()
End Sub
Protected Overloads Overrides Sub CreateChildElements()
MyBase.CreateChildElements()
checkbox = New RadCheckBoxElement()
AddHandler checkbox.ToggleStateChanged, AddressOf checkbox_ToggleStateChanged
Me.Children.Add(checkbox)
End Sub
Protected Overloads Overrides Function ArrangeOverride(ByVal finalSize As SizeF) As SizeF
Dim size As SizeF = MyBase.ArrangeOverride(finalSize)
Dim rect As RectangleF = GetClientRectangle(finalSize)
Me.checkbox.Arrange(New RectangleF((finalSize.Width - Me.checkbox.DesiredSize.Width) / 2, (rect.Height - 20) / 2, 20, 20))
Return size
End Function
Public Overloads Overrides Function IsCompatible(ByVal data As Telerik.WinControls.UI.GridViewColumn, ByVal context As Object) As Boolean
Return data.Name = "Select" AndAlso TypeOf context Is GridTableHeaderRowElement AndAlso MyBase.IsCompatible(data, context)
End Function
Private Sub checkbox_ToggleStateChanged(ByVal sender As Object, ByVal args As StateChangedEventArgs)
If Not suspendProcessingToggleStateChanged Then
Dim valueState As Boolean = False
If args.ToggleState = Telerik.WinControls.Enumerations.ToggleState.[On] Then
valueState = True
End If
Me.GridViewElement.EditorManager.EndEdit()
Me.TableElement.BeginUpdate()
For i As Integer = 0 To Me.ViewInfo.Rows.Count - 1
Me.ViewInfo.Rows(i).Cells(Me.ColumnIndex).Value = valueState
Next
Me.TableElement.EndUpdate(False)
Me.TableElement.Update(GridUINotifyAction.DataChanged)
End If
End Sub
Private suspendProcessingToggleStateChanged As Boolean
Public Sub SetCheckBoxState(ByVal state As Telerik.WinControls.Enumerations.ToggleState)
suspendProcessingToggleStateChanged = True
Me.checkbox.ToggleState = state
suspendProcessingToggleStateChanged = False
End Sub
Public Overrides Sub Attach(ByVal data As Telerik.WinControls.UI.GridViewColumn, ByVal context As Object)
MyBase.Attach(data, context)
AddHandler Me.GridControl.ValueChanged, AddressOf GridControl_ValueChanged
End Sub
Public Overrides Sub Detach()
If Me.GridControl IsNot Nothing Then
RemoveHandler Me.GridControl.ValueChanged, AddressOf GridControl_ValueChanged
End If
MyBase.Detach()
End Sub
Private Sub GridControl_ValueChanged(ByVal sender As Object, ByVal e As EventArgs)
Dim editor As RadCheckBoxEditor = TryCast(sender, RadCheckBoxEditor)
If editor IsNot Nothing Then
Me.GridViewElement.EditorManager.EndEdit()
If DirectCast(editor.Value, ToggleState) = ToggleState.Off Then
SetCheckBoxState(ToggleState.Off)
Else
Dim found As Boolean = False
For Each row As GridViewRowInfo In Me.ViewInfo.Rows
If row.Equals(Me.RowInfo) = False AndAlso row.Cells(Me.ColumnIndex).Value Is Nothing OrElse Not CBool(row.Cells(Me.ColumnIndex).Value) Then
found = True
Exit For
End If
Next
If Not found Then
SetCheckBoxState(ToggleState.[On])
End If
End If
End If
End Sub
End Class
You can download a complete VB and C# project from the following link.