David Shochet
David Shochet

Reputation: 5375

Radio buttons binding in .Net MAUI: selected item is not updated in the view model

I have a .Net MAUI app that uses CommunityToolkit.Mvvm.

Here is a part of my view model:

    [ObservableProperty]
    private DateTime _selectedTime;

    public List<DateTime> Times { get; set; } = new ()
        { new DateTime(2000, 1, 1, 9, 0, 0), new DateTime(2000, 1, 1, 9, 30, 0), new DateTime(2000, 1, 1, 10, 0, 0), new DateTime(2000, 1, 1, 10, 30, 0),
          new DateTime(2000, 1, 1, 11, 0, 0), new DateTime(2000, 1, 1, 11, 30, 0), new DateTime(2000, 1, 1, 12, 0, 0), new DateTime(2000, 1, 1, 12, 30, 0),
          new DateTime(2000, 1, 1, 13, 0, 0), new DateTime(2000, 1, 1, 13, 30, 0), new DateTime(2000, 1, 1, 14, 0, 0), new DateTime(2000, 1, 1, 14, 30, 0),
          new DateTime(2000, 1, 1, 15, 0, 0), new DateTime(2000, 1, 1, 15, 30, 0), new DateTime(2000, 1, 1, 16, 0, 0), new DateTime(2000, 1, 1, 16, 30, 0) };

Here is a part of the page:

        <CollectionView 
            ItemsSource="{Binding Times}" 
            SelectionMode="Single"
            ItemsLayout="VerticalGrid, 3">
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <RadioButton Content="{Binding ., StringFormat='{0:hh:mm tt}'}">
                            <RadioButton.IsChecked>
                                <Binding Path="BindingContext.SelectedTime"
                                     Source="{RelativeSource AncestorType={x:Type local:AppointmentSchedulePage}}" 
                                     Converter="{StaticResource DateTimeConverter}"
                                     ConverterParameter="{Binding .}" 
                                     Mode="TwoWay"/>
                            </RadioButton.IsChecked>
                        </RadioButton>
                    </Grid>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>

Here is the converter:

public class DateTimeConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is DateTime selectedDateTime && parameter is DateTime itemDateTime)
        {
            return selectedDateTime.Equals(itemDateTime);
        }

        return false;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is bool isChecked && isChecked && parameter is DateTime itemDateTime)
        {
            return itemDateTime;
        }

        return Binding.DoNothing;
    }
}

Though I am not sure that the converter is needed in my scenario.

The radio buttons are displayed correctly:

enter image description here

But the SelectedTime property in the viewmodel is not updated, and its setter is not hit. What am I missing?

Upvotes: 2

Views: 2102

Answers (1)

ToolmakerSteve
ToolmakerSteve

Reputation: 21243

See RadioButton / Respond to a property change.

If you group radio buttons (assign them to the same group), then you can bind to the selected value of the RadioButtonGroup:

<CollectionView RadioButtonGroup.GroupName="MyGroup"
        RadioButtonGroup.SelectedValue="{Binding SelectedRadioButton}">
    ...
    <DataTemplate>
        <RadioButton GroupName="MyGroup" ... />
// Try this first with type "object", and see what it gets set to.
// Then maybe can change it to a specific type; not sure.
public object SelectedRadioButton { get; set; }

NOTE: Because the buttons are inside ItemTemplate/DataTemplate, tell each one the groupname; AFAIK that is not automatically passed down from collectionview into the datatemplate.

Upvotes: 2

Related Questions