This is a migrated thread and some comments may be shown as answers.

Radiobutton selection of a row

1 Answer 347 Views
DataGrid
This is a migrated thread and some comments may be shown as answers.
jeljeljel
Top achievements
Rank 2
jeljeljel asked on 09 Jul 2019, 07:25 PM

Can someone post a code example that shows a DataGrid with the first column being a RadioButton control, and clicking the radio button on a row...

a) invokes a Command that the radio button was clicked

b) all other row's radio buttons become unchecked (so only one row's radio button is checked at any given time)

1 Answer, 1 is accepted

Sort by
0
Lance | Manager Technical Support
Telerik team
answered on 09 Jul 2019, 10:06 PM
Hi jeljeljel,

The issue you're going to face is that the DataGrid doesn't have built-in support for a SelectionColumn. Although it does have a BooleanColumn, this is only related to the data item and not the selection of the row. If you would like to see the RadDataGrid have a built-in selection column, please open a Feature Request here - UI for Xamarin Feedback Portal.

Custom Development

In the meantime,  you will need to develop a custom approach with custom syncing logic. You could try using the DataGridTemplateColumn with a RadCheckBox (there's no RadioButton in Xamarin.Forms).

Attached is an example to get you started, below is the relevant code (you'll want to open the solution in Visual Studio to restore the dependencies).

             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:SelectionColumnDemo.Portable"
             xmlns:telerikPrimitives="clr-namespace:Telerik.XamarinForms.Primitives;assembly=Telerik.XamarinForms.Primitives"
             xmlns:telerikGrid="clr-namespace:Telerik.XamarinForms.DataGrid;assembly=Telerik.XamarinForms.DataGrid"
             x:Class="SelectionColumnDemo.Portable.MainPage">
 
    <ContentPage.BindingContext>
        <local:MainViewModel x:Name="ViewModel"/>
    </ContentPage.BindingContext>
 
    <Grid>
        <telerikGrid:RadDataGrid x:Name="PeopleDataGrid"
                                 ItemsSource="{Binding People}"
                                 SelectionChanged="PeopleDataGrid_OnSelectionChanged"
                                 SelectionMode="Single"
                                 SelectionUnit="Row"
                                 AutoGenerateColumns="False">
            <telerikGrid:RadDataGrid.Columns>
                <telerikGrid:DataGridTemplateColumn HeaderText="Template Column">
                    <telerikGrid:DataGridTemplateColumn.CellContentTemplate>
                        <DataTemplate>
                            <telerikPrimitives:RadCheckBox IsChecked="{Binding IsPersonSelected}"
                                             IsCheckedChanged="RadCheckBox_OnIsCheckedChanged" />
                        </DataTemplate>
                    </telerikGrid:DataGridTemplateColumn.CellContentTemplate>
                </telerikGrid:DataGridTemplateColumn>
                <telerikGrid:DataGridTextColumn PropertyName="Name" HeaderText="Name" />
            </telerikGrid:RadDataGrid.Columns>
        </telerikGrid:RadDataGrid>
    </Grid>
</ContentPage>

public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();
    }
 
    // Updates the DataGrid's SelectedItem when the checkbox is changed (which triggers SelectionChanged)
    private void RadCheckBox_OnIsCheckedChanged(object sender, IsCheckedChangedEventArgs e)
    {
        // this logic requires both the Person reference and the IsChecked value
        if (sender is RadCheckBox cb && cb.BindingContext is SelectablePerson person)
        {
            if (e.NewValue == true)
            {
                PeopleDataGrid.SelectedItem = person;
            }
            else if (e.NewValue == false)
            {
                PeopleDataGrid.SelectedItem = null;
                person.IsPersonSelected = false;
            }
        }
    }
 
    // Updates the check boxes when the DataGrid selection changes (clicking anywhere but the checkbox)
    private void PeopleDataGrid_OnSelectionChanged(object sender, DataGridSelectionChangedEventArgs e)
    {
        if (e.AddedItems != null && e.AddedItems.First() is SelectablePerson selectedPerson)
        {
            foreach (var person in ViewModel.People)
            {
                if (person.Name == selectedPerson.Name)
                {
                    // Causes the selected item's checkbox to become checked
                    person.IsPersonSelected = true;
                }
                else
                {
                    // Uncheck every other checkbox
                    person.IsPersonSelected = false;
                }
            }
        }
    }
}

public class MainViewModel : ViewModelBase
{
    public MainViewModel()
    {
        foreach (var name in SampleDataService.Current.GeneratePeopleNames())
        {
            People.Add(new SelectablePerson { Name = name });
        }
    }
 
    public ObservableCollection<SelectablePerson> People { get; set; } = new ObservableCollection<SelectablePerson>();
}
 
public class SelectablePerson : BindableBase
{
    private string name;
    private bool isPersonSelected;
 
    public string Name
    {
        get => name;
        set => SetProperty(ref name, value);
    }
 
    public bool IsPersonSelected
    {
        get => isPersonSelected;
        set => SetProperty(ref isPersonSelected, value);
    }
}


Important Notes about the Demo

Prototype
The project is a proof of concept for one of the potential cases for a custom scenario. It is not fully tested and will require additional null checks, safety fallbacks and other design considerations. Please do not copy/paste the code into a production or non-prototype scenario without fully testing it for your use case.

MVVM
The demo uses the IsCheckedChanged event handler to keep the SelectedItem synced. You could try to move to a command-only approach, but it will require some additional additional re-design that might ultimately not be possible without breaking MVVM. This is because the syncing logic in the OnIsCheckedChanged event handler requires both the IsChecked value and the Person reference.


Further Assistance

For Telerik API Related Issues/Questions

If you have any trouble with the Telerik-specific APIs and features, please open a Support Ticket and share the code you're using so that we can investigate the issue directly. 

For General Xamarin.Forms, .NET and MVVM Issues/Questions

If you have any general Xamarin.Forms or MVVM questions, I recommend StackOverflow or Xamarin Forums instead of this forum (e.g. how to pass two values in a CommandParameter).

You'll be able to get quicker a general development answer from the community as they can help with non-Telerik issues. You can visit the scope of support article to know what is and isn't covered by Telerik support (i.e. custom app and general .NET development is out of scope).

I hope this demo is useful and helps get you started.

Regards,
Lance | Technical Support Engineer, Principal
Progress Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Tags
DataGrid
Asked by
jeljeljel
Top achievements
Rank 2
Answers by
Lance | Manager Technical Support
Telerik team
Share this question
or