DataGrid Row Selection Binding to a DataGridBooleanColumn

1 Answer 75 Views
CheckBox DataGrid
Nathan
Top achievements
Rank 1
Nathan asked on 21 Sep 2023, 05:22 PM

I have the DataGrid SelectionUnit set to Row and SelectionMode set to Multiple.

I'm trying to add a DataGridBooleanColumn that has a check box in the header and for each row. I would like to bind the IsChecked property of the checkbox to if the Row is selected or not.   

The check box in the header would either select all or deselect all depending on if it is checked or not.  I was able to use the SelectAll and DeselectAll methods which selects all the rows, but it does not check the checkbox at the row level if the row is selected.

Is there a way to do this?

 

 

1 Answer, 1 is accepted

Sort by
0
Maria
Telerik team
answered on 26 Sep 2023, 01:28 PM

Hello Nathan,

There are two options that I can propose to achieve the select all/ deselect all.

1. You can use the HeaderContentTemplate of the DataGrid column. In this template,  you can add a CheckBox control. Then bind the IsChecked to a property in the ViewModel that implements property changed.

 <Grid>
        <telerik:RadDataGrid x:Name="dataGrid"
                             ItemsSource=""
                             AutoGenerateColumns="False">
            <telerik:RadDataGrid.Columns>
                <telerik:DataGridBooleanColumn PropertyName="IsChampion" 
                                               HeaderText="Champion?">
                    <telerik:DataGridColumn.CellContentTemplate>
                        <DataTemplate>
                            <CheckBox IsChecked="{Binding Your property here}"/>
                        </DataTemplate>
                    </telerik:DataGridColumn.CellContentTemplate>
                </telerik:DataGridBooleanColumn>
            </telerik:RadDataGrid.Columns>
        </telerik:RadDataGrid>
    </Grid>

2. The second option is to use a command. The DataGrid control has a ColumnHeaderTap command that is executed when tapping on a header. 

public class ColumnHeaderTapCommand : DataGridCommand
{
    public ColumnHeaderTapCommand()
    {
        Id = DataGridCommandId.ColumnHeaderTap;
    }
    public override bool CanExecute(object parameter)
    {
        return true;
    }
    public override void Execute(object parameter)
    {
        if (parameter is Telerik.Maui.Controls.Compatibility.DataGrid.DataGridBooleanColumn)
        {
            // sample logic implementation. You have to extend it further. 
            var data = (this.BindingContext as ViewModel).Clubs;
            foreach (var item in data)
            {
                if (item.IsChampion == true)
                {
                    item.IsChampion = false;
                }
                else if (item.IsChampion == false)
                {
                    item.IsChampion = true;
                }
            }
        }
// default command execution for other columnselse this.Owner.CommandService.ExecuteDefaultCommand(DataGridCommandId.ColumnHeaderTap, parameter); } }


Regarding to the IsChecked property for column. You have the SelectedItem property which is Bindable. Create a property in the ViewModel and Bind it to the SelectedItem property. Implement property changed interface and additional logic to update the IsChecked property value depending on whether the item is selected or not. 

Regards,
Maria
Progress Telerik

A brand new .NET MAUI course was just added to the Virtual Classroom. The training course is developed to help you get started with the Telerik UI for .NET MAUI components and features. It aims to put you in the shoes of an engineer who adds new features to an existing application. You can check it out at https://learn.telerik.com
Clint
Top achievements
Rank 1
Iron
Iron
commented on 17 Oct 2023, 08:55 PM

I'm trying to implement this functionality as well. Looking at the original post, I don't see where this would work. The idea is to be able to select all rows under a particular group. If you look at the first screen shot below from a Windows forms application I have, I can do that because I can click the check box in the header under the group.

If you look at the second screen shot from the MAUI application I'm working, I only have the headers at the top, so I don't have a checkbox to indicate to a user where to click to select all records under a particular group.

Using RadDataGrid under MAUI, what's the best way to implement functionality to check the boxes for each row under a particular group?

 

 

 

Didi
Telerik team
commented on 18 Oct 2023, 06:09 AM

Hi Clint,

You can use the GroupHeaderTap command, or add a checkbox control in the GroupHeader by using the GroupHeaderTemplate.

When using the command you can change the state of the property bound to the Checkbox IsChecked property. This approach requires custom logic implementation. 
All commands that DataGrid provides are described here: https://docs.telerik.com/devtools/maui/controls/datagrid/commands/overview 

Clint
Top achievements
Rank 1
Iron
Iron
commented on 20 Oct 2023, 12:07 AM

I added the below, which works great. However, I'm using AggregateDescriptors to display the total number of records under each group when grouping. This is overriding those aggregate totals now. 

Is there a way to add the aggregates to the template? Or am I going to have to add them somehow to the text binding on the label?

                <telerik:RadDataGrid.GroupHeaderTemplate>

                    <DataTemplate>
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition/>
                            </Grid.ColumnDefinitions>
                            <CheckBox Grid.Column="0"
                                      Margin="0,0,0,0"
                                      VerticalOptions="Center" 
                                      HorizontalOptions="Center" />
                            <Label Grid.Column="1"
                               Text="{Binding}"
                               VerticalOptions="Center"
                               HorizontalOptions="Start" />

                        </Grid>
                    </DataTemplate>
                </telerik:RadDataGrid.GroupHeaderTemplate>
Didi
Telerik team
commented on 20 Oct 2023, 07:20 AM

The aggregates are applied to column or group based on whether the ShowGroupFooter or ShowColumnFooter is set. Also you can display them in the group header by setting the ShowGroupHeaderAggregates

If you want to apply custom function on the aggregates, then you can use the Delegate Aggregate Descriptor: https://docs.telerik.com/devtools/maui/controls/datagrid/aggregates/delegate-aggregate-descriptor 

If you want to display the aggregates values in the GroupHeaderTemplate. Bind the AggregateValues collection of the GroupHeaderContext, then you can use a converter to display the values. Here is a sample example without converter. 

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:telerik="http://schemas.telerik.com/2022/xaml/maui"
             xmlns:local="clr-namespace:MauiApp19"
             xmlns:gridContext="clr-namespace:Telerik.Maui.Controls.Compatibility.DataGrid;assembly=Telerik.Maui.Controls.Compatibility"
             x:Class="MauiApp19.MainPage">
    <Grid RowDefinitions="auto,*">
        <Button Clicked="Button_Clicked" Text="get data" />
        <telerik:RadDataGrid Grid.Row="1" x:Name="grid" ShowGroupFooters="True" ShowGroupHeaderAggregates="True"
                     ItemsSource="{Binding Persons}"
                     AutoGenerateColumns="False" SelectionMode="Single" SelectionUnit="Row"
                     >
            <telerik:RadDataGrid.Columns>
                <telerik:DataGridTextColumn x:Name="nameColumn" PropertyName="Name"/>
                <telerik:DataGridNumericalColumn PropertyName="Age"/>
                <telerik:DataGridTextColumn PropertyName="City" HeaderText="City" FooterText="hellooo count">
                    <telerik:DataGridTextColumn.AggregateDescriptors>
                        <telerik:PropertyAggregateDescriptor PropertyName="City"
                                                     Function="Count"
                                                     Caption="Total count: " />
                    </telerik:DataGridTextColumn.AggregateDescriptors>
                </telerik:DataGridTextColumn>

            </telerik:RadDataGrid.Columns>
            <telerik:RadDataGrid.GroupHeaderTemplate>
                <DataTemplate x:DataType="gridContext:GroupHeaderContext">
                    <HorizontalStackLayout>
                        <Label Text="{Binding AggregateValues}" />
                        <Label Text="{Binding Group.Key}" />
                    </HorizontalStackLayout>
                </DataTemplate>
            </telerik:RadDataGrid.GroupHeaderTemplate>
        </telerik:RadDataGrid>
    </Grid>

</ContentPage>

Clint
Top achievements
Rank 1
Iron
Iron
commented on 20 Oct 2023, 09:06 PM

I used the following, but I'm getting an error, see screenshot at the bottom. I'm using a DataTable as the source for the grid.

I get aggregate totals in the group footer, and I get them if I remove the header template.

<telerik:RadDataGrid
        x:Name="dataGridPlugins"
        Grid.Row="5"
        Margin="0,10,0,0"
        ItemsSource="{Binding}"            
        ShowGroupHeaderAggregates="True"
        ShowGroupFooters="True"
        UserEditMode="Cell"
        CurrentCellChanged="DataGrid_OnCurrentCellChanged"
        SelectionChanged="DataGrid_SelectionChanged"               
        SelectionUnit="Row"
        SelectionMode="Multiple"
        ToolTipProperties.Text=""
        AutoGenerateColumns="True" >

        <telerik:RadDataGrid.Columns>
                <telerik:DataGridBooleanColumn PropertyName="Select"
                                               HeaderText="Select">
                    <telerik:DataGridColumn.CellContentTemplate>
                        <DataTemplate>
                            <CheckBox IsChecked="{Binding Select}"
                                      VerticalOptions="Center"
                                      PropertyChanged="OnCheckboxChanged"
                                      HorizontalOptions="Center"/>
                        </DataTemplate>
                    </telerik:DataGridColumn.CellContentTemplate>
            <telerik:DataGridBooleanColumn.AggregateDescriptors>
                <telerik:PropertyAggregateDescriptor PropertyName="PluginID"
                                                         Function="Count"
                                                         Caption="Total:"/>
            </telerik:DataGridBooleanColumn.AggregateDescriptors>
        </telerik:DataGridBooleanColumn>
            <telerik:DataGridTemplateColumn>
                    <telerik:DataGridTemplateColumn.CellContentTemplate>
                        <DataTemplate>
                            <Button Text="Generate"
                                    CommandParameter="{Binding}"
                                    Clicked="GenerateButton_Clicked"/>
                        </DataTemplate>
                    </telerik:DataGridTemplateColumn.CellContentTemplate>
                </telerik:DataGridTemplateColumn>
        </telerik:RadDataGrid.Columns>

    <telerik:RadDataGrid.GroupHeaderTemplate>
        <DataTemplate x:DataType="gridContext:GroupHeaderContext">
            <HorizontalStackLayout>
                <CheckBox VerticalOptions="Center" 
                              HorizontalOptions="Center" />
                <Label Text="{Binding Group.Key}" VerticalOptions="Center" />
                <Label Text="{Binding AggregateValues}" VerticalOptions="Center" />
            </HorizontalStackLayout>
        </DataTemplate>
    </telerik:RadDataGrid.GroupHeaderTemplate>

 

 

Didi
Telerik team
commented on 23 Oct 2023, 07:31 AM

Hi Clint, in my previous comment I wrote the following: 
If you want to display the aggregates values in the GroupHeaderTemplate. Bind the AggregateValues collection of the GroupHeaderContext, then you can use a converter to display the values. Here is a sample example without converter. 

You have the aggregates values, how to display them in the template is up to you. You can use converter. 

 

Tags
CheckBox DataGrid
Asked by
Nathan
Top achievements
Rank 1
Answers by
Maria
Telerik team
Share this question
or