Radiobutton selection of a row

2 posts, 0 answers
  1. jeljeljel
    jeljeljel avatar
    20 posts
    Member since:
    Nov 2006

    Posted 09 Jul 2019 Link to this post

    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)

  2. Lance | Manager Technical Support
    Admin
    Lance | Manager Technical Support avatar
    1195 posts

    Posted 09 Jul 2019 Link to this post

    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
Back to Top