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

RadCheckBox as a radio button

8 Answers 213 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Mir
Top achievements
Rank 1
Mir asked on 26 Jun 2018, 07:38 PM
Is it possible to add multiple RadCheckBoxes on a form and they can have behave where when one gets selected all the other get unselected?

8 Answers, 1 is accepted

Sort by
0
Lance | Manager Technical Support
Telerik team
answered on 26 Jun 2018, 09:22 PM
Hi Mir,

Currently, the RadCheckBox doesn't have a Group property that would allow exclusive selection. I have submitted this as a feature request: CheckBox: Exclusive Selection

In the meantime, you can programmatically uncheck any checkboxes

myRadCheckBox.IsChecked = false;


Regards,
Lance | Tech Support Engineer, Sr.
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
0
George
Top achievements
Rank 1
answered on 22 Jan 2020, 01:48 PM

Hi, Lance

Any update on this? How to implement 'Radio button' from the checkbox, if the checkbox are listed inside a listview and using MVVM?

0
Lance | Manager Technical Support
Telerik team
answered on 22 Jan 2020, 03:11 PM

Hi George,

You can keep track of the feature request's progress by clicking the  "Follow" button on the feedback item's page (use the link I shared in my last reply). That item shows the current progress. "Approved" means that the team believes it will be a useful feature, but it has not started development yet. When they start development, you will be notified and at the status will change to "In Development".

Did you try my suggestion of using the IsChecked property to allow for grouped checkboxes?  The fact that the CheckBoxes will be in a DataTemplate doesn't change anything. You'd still be binding to the RadCheckBox.IsChecked property to de-select it.

I will reply to the feedback item with a demo project showing how to accomplish this.

Regards,
Lance | Team Lead - US DevTools Support
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
0
George
Top achievements
Rank 1
answered on 23 Jan 2020, 06:09 AM

Hi Lance,

If you provide a demo project it will be very useful.

The following is my listview where I use the checkbox.

                        <ListView ItemsSource="{Binding StudyParameterGrouped}"
                                  MinimumHeightRequest="100"
                                  HeightRequest="{Binding Height}"
                                  IsGroupingEnabled="true">
                            <ListView.GroupHeaderTemplate>
                                <DataTemplate>
                                    <ViewCell>
                                        <Grid>
                                            <Grid.ColumnDefinitions>
                                                <ColumnDefinition Width="Auto"/>
                                                <ColumnDefinition Width="Auto"/>
                                            </Grid.ColumnDefinitions>
                                            <Label Grid.Column="0" Text="{Binding GroupDisplayText}"
                                                 FontSize="Large"
                                                 FontFamily="{StaticResource BoldFont}"
                                                 TextColor="#132275" VerticalOptions="Center"/>
                                            <Label VerticalTextAlignment="Start" VerticalOptions="Start"
                                                   HorizontalOptions="Start" Grid.Column="1" Text="*"
                                                   TextColor="Red"
                                                   FontSize="Medium"
                                                   FontFamily="{StaticResource RegularFont}" />
                                        </Grid>
                                    </ViewCell>
                                </DataTemplate>
                            </ListView.GroupHeaderTemplate>
                            <ListView.ItemTemplate>
                                <DataTemplate>
                                    <ViewCell>
                                        <ViewCell.View>
                                            <StackLayout HorizontalOptions="FillAndExpand" Orientation="Horizontal" Padding="10  ">
                                                <telerikPrimitives:RadCheckBox x:Name="checkbox" VerticalOptions="Center" IsChecked="{Binding IsSelected, Mode=TwoWay}">
                                                </telerikPrimitives:RadCheckBox>
                                                <Label Text="{Binding ParameterDisplayText,FallbackValue='Not Found', Mode=TwoWay, Converter={StaticResource nothingCoverter}}" HorizontalOptions="StartAndExpand" FontSize="Medium" FontFamily="{StaticResource RegularFont}"/>
                                            </StackLayout>
                                        </ViewCell.View>
                                    </ViewCell>
                                </DataTemplate>
                            </ListView.ItemTemplate>
                        </ListView>
0
Didi
Telerik team
answered on 23 Jan 2020, 10:23 AM

Hi George,

My colleague Lance provided a sample demo about how to implement grouping RadCheckBoxes to achieve exclusive selection.

The demo can be found in the RadCheckBox: Exclusive selection feature request in our feedback portal. Please navigate to feedback item and review the provided example. Note that this is just a sample demo and it is up to you how to implement the business logic needed based on the requirement you have.

Regards,
Didi
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
0
George
Top achievements
Rank 1
answered on 24 Jan 2020, 04:39 PM

Hi Didi,

I tried the provided sample and it's working in the sense, if we create a group of "GroupedCheckBox" one by one; but if we try to create the same group of "GroupedCheckBox" from a listview then it's not working.

This is code behind of Test

public class SourceItem
 {
     public string Name { get; set; }
     public bool IsSelected { get; set; }
 }
 
public List<SourceItem> Source { get; set; }
 
   public Test()
     {
         this.Source = new List<SourceItem>
         {
             new SourceItem() { Name= "Red", IsSelected = true},
             new SourceItem(){ Name= "Green", IsSelected = false },
             new SourceItem(){ Name= "Blue", IsSelected = false},
         };
         this.BindingContext = this;
         InitializeComponent();
     }

This is my content of Test Xaml

<Grid Padding="10">
    <StackLayout Spacing="5">
        
        <Label Text="Exclusive Color Selection" />
        <ListView ItemsSource="{Binding Source, Mode=TwoWay}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <StackLayout Orientation="Horizontal">
                            <local:GroupedCheckBox GroupName="Color" IsChecked="{Binding IsSelected, Mode=TwoWay}"/>
                            <Label x:Name="labellist" Text="{Binding Name, Mode=TwoWay}"/>
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
        <!--<StackLayout Orientation="Horizontal">
            <local:GroupedCheckBox GroupName="Color"
                               IsChecked="True"
                               Margin="0,0,10,0" />
            <Label Text="Red" />
        </StackLayout>
        <StackLayout Orientation="Horizontal">
            <local:GroupedCheckBox GroupName="Color"
                               Margin="0,0,10,0" />
            <Label Text="Green" />
        </StackLayout>
        <StackLayout Orientation="Horizontal">
            <local:GroupedCheckBox GroupName="Color"
                               Margin="0,0,10,0" />
            <Label Text="Blue" />
        </StackLayout>-->
    </StackLayout>
</Grid>
0
Lance | Manager Technical Support
Telerik team
answered on 24 Jan 2020, 06:03 PM

Hi George,

Please read the "Important" section from my reply:

The demo is hard-coded to expect a Grid at the top of the Visual Tree. 

In your case, you have the item in a ListView ItemTemplate, this is a very different scenario as ListView items are Templated views (which are essentially "view islands" in the page).

Traversing the ListView Visual Tree

You'll have to rewrite the visual tree explorer code. Please visit the Xamarin.Forms post I linked to in the demo code, you will find this "Modified for ListView" answer at the bottom:

Notice that line of code I call out in the red box. It also looks for TemplatedItems, which are the ListView items.

You will need to rewrite the custom GroupedCheckBox class to go up to the ListView or Page level, then traverse down to the ListView.

Further Assistance with Visual Tree

Ultimately, we are unable to write a custom visual tree traverser for your UI as this falls under Professional Services Custom App Development.  

If you do need help writing the code, I recommend posting in Xamarin.Forms forums and ask for assistance with the Xamarin APIs for traversing the Visual Tree of items in a ListView. You can also hop into a Slack channel the Xamarin development community to get some real-time help https://xamarinchat.herokuapp.com/ .

The question you want to ask is "How do I traverse the visual tree of every item in Xamarin.Forms ListView ItemTemplate"?

 

Important Side Note:

Even if we did have an official GroupName feature available, you still would not be able to group checkboxes in other DataTemplate instances as XAML is intentionally designed this way.

Regards,
Lance | Team Lead - US DevTools Support
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
0
Lance | Manager Technical Support
Telerik team
answered on 24 Jan 2020, 06:56 PM

Hi George,

I've reviewed your scenario again. You do not need any specially designed checkbox or group because the IsChecked is TwoWay bound to the data model's IsSelected property.

Make sure SourceItem is using PropertyChanged notification:

public class SourceItem : INotifyPropertyChanged
{
    public string Name { get; set; }

    private bool isSelected;
    public bool IsSelected
    {
        get => isSelected;
        set
        {
            if (isSelected != value)
            {
                isSelected = value;
                OnPropertyChanged();
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

Subscribe to the RadCheckbox IsCheckChanged event

<ListView ItemsSource="{Binding Source, Mode=TwoWay}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <StackLayout Orientation="Horizontal">
                    <telerikPrimitives:RadCheckBox
                        IsChecked="{Binding IsSelected, Mode=TwoWay}" 
                        IsCheckedChanged="RadCheckBox_OnIsCheckedChanged"/>
                    <Label x:Name="labellist"
                           Text="{Binding Name, Mode=TwoWay}" />
                </StackLayout>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

 

Now you can iterate over the other data items in the list and update them:

private void RadCheckBox_OnIsCheckedChanged(object sender, IsCheckedChangedEventArgs e)
{
    if (e.NewValue == true && sender is RadCheckBox cb)
    {
        var checkedItem = cb.BindingContext as SourceItem;

        foreach (var item in Source)
        {
            if (item != checkedItem)
            {
                // Make all the other items unselected
                item.IsSelected = false;
            }
        }
    }
}

This has a significant speed advantage over the Visual tree lookup and you don't need any customization.

Regards,
Lance | Team Lead - US DevTools Support
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
General Discussions
Asked by
Mir
Top achievements
Rank 1
Answers by
Lance | Manager Technical Support
Telerik team
George
Top achievements
Rank 1
Didi
Telerik team
Share this question
or