Rahul Sureshbabu
Rahul Sureshbabu

Reputation: 11

How to bind Radio Button group created dynamically using Data Template to a List?

I have a list called "CarEngineItems" of "SelectableItems" objects with 2 properties: ItemDescription and isSelected.

    namespace DTOs
    {
        class CarEngines : INotifyPropertyChanged
        {
            public static List<SelectableItem> CarEngineItems { get; set; } = new List<SelectableItem>();
    
            public event PropertyChangedEventHandler PropertyChanged;
            protected void OnPropertyChanged(string name)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
            }
        }
    }

 namespace Models
    {
        public class SelectableItem : INotifyPropertyChanged
        {
            public string ItemDescription { get; set; }
            public bool IsSelected { get; set; }
    
            public event PropertyChangedEventHandler PropertyChanged;
    
            protected void OnPropertyChanged(string name)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
            }
        }
    }

I have used the below user control to create a radio button for each item in the list.

<UserControl.Resources>
        <SelectableItem:SelectableItem x:Key="vm"></SelectableItem:SelectableItem>
        <src:RadioButtonCheckedConverter x:Key="RadioButtonCheckedConverter" />
        <CollectionViewSource
                Source="{Binding Source={x:Static Application.Current}, Path=ItemDescription}"
                x:Key="ListingDataView" />
        <DataTemplate x:Key="GroupingHeaderTemplate">
            <TextBlock Text="{Binding Path=Name}" Style="{StaticResource GroupHeaderStyle}"/>
        </DataTemplate>
    </UserControl.Resources>
    <Grid>
        <ItemsControl Name="RadioGroup" AutomationProperties.Name="RadioGroup" >
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <RadioButton                              
                                 Content="{Binding Path=ItemDescription}"
                                 FlowDirection="RightToLeft"
                                 IsChecked="{Binding Path=IsSelected, Mode=TwoWay}" Style="{DynamicResource CustomRadioButton}" Margin="20,0"/>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
    </Grid>
</UserControl>

I added this user control to my main window.

 <uc:CommonRadioButtonGroup x:Name="EnginesGroup"></uc:CommonRadioButtonGroup>

In the code behind, I updated the source to this user control as:

 InitializeComponent();
 EnginesGroup.RadioGroup.ItemsSource = DTOs.CarEngines.CarEngineItems;

The CarEngineItems were added at startup.

CarEngines.CarEngineItems.Add(new SelectableItem
            {
                ItemDescription = "V8",
                IsSelected = Properties.Settings.Default.Engines.Equals("V8")
            });
            CarEngines.CarEngineItems.Add(new SelectableItem
            {
                ItemDescription = "Electric",
                IsSelected = Properties.Settings.Default.Engines.Equals("Electric")
            });

The current output results in this: On startup, the the default value V8 is selected as expected.

Proper binding happens on startup.

But on clicking the next item in group, it is also selected.

Why are both selected?

The ultimate aim is to select a check box (created dynamically) and update only the selected item to a property table on pressing a button (SAVE button). But in this case, the selection is happening for all items.

Upvotes: 0

Views: 868

Answers (1)

Rahul Sureshbabu
Rahul Sureshbabu

Reputation: 11

Based on @o_w 's comment, I am updating the answer.

I added a group name to the Radio Button Group by binding it to another property of SelectableItem.

 <ItemsControl Name="RadioGroup" AutomationProperties.Name="RadioGroup" >
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <RadioButton
                                 GroupName="{Binding Path=ItemType}"
                                 Content="{Binding Path=ItemDescription}"
                                 FlowDirection="RightToLeft"
                                 IsChecked="{Binding Path=IsSelected, Mode=TwoWay}" 
                                 Style="{DynamicResource CustomRadioButton}" Margin="20,0"/>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>

Here's the updated SelectableItem.

namespace Models
{
    public class SelectableItem : INotifyPropertyChanged
    {
    public string ItemDescription { get; set; }
    public bool IsSelected { get; set; }
    public string ItemType { get; set; }//New

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string name)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }
}
}

Upvotes: 1

Related Questions