Search code examples
c#wpfdatagridradio-buttondatagridtemplatecolumn

Synchronise Radiobutton Selection with Row selection in a datagrid


I have a RadioButtonTemplateColumn in my datagrid. When the radiobutton is clicked, the corresponding row gets selected, but when the row is clicked the corresponding radiobutton is not selected. This leaves the system in a 'confused' state as the radiobutton and row selection are not in sync. Please how do I synchronise them? I have reviewed a similar response but it did not resolve the issue or me.

Below is the code I have written:

            <DataGrid.Columns>
                <DataGridTemplateColumn>
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <RadioButton GroupName="Select" IsChecked="{Binding IsSelected, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
                <DataGridTextColumn Width="Auto" Header="First Name" Binding="{Binding FirstName}"/>
                <DataGridTextColumn Width="Auto" Header="Last Name" Binding="{Binding LastName}"/>
            </DataGrid.Columns>
        </DataGrid>

Solution

  • The problem is that your binding is invalid. If you use a tool like Snoop Wpf or the live visual tree in Visual Studio, you'll see that your binding isn't working.

    The reason why is that your RadioButton is inside a template which has the data context of the data that the grid is bound to - not the DataGridRow. If you update your binding like so, it will work:

    IsChecked="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}, Path=IsSelected, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" 
    

    Essentially, I told the binding to look for IsSelected relative to the DataGridRow higher up in the visual tree.

    Another problem is that because you're using a RadioButton it cannot be un-selected when clicking on it. If you want it to act like a toggle, you should use a CheckBox instead.

    I hope this helps.