wpfxamlcontroltemplateischecked

WPF - Radio button control template binding "IsChecked" not working


I have a control template like below, and I want to get IsChecked property when user selects a radio button.

But when user select radio button "A" it's IsChecked property still show false. Why?

<ControlTemplate x:Key="RadioBtnTemplate" TargetType="{x:Type RadioButton}">
   <Grid>
     <StackPanel Margin="5">
         <RadioButton Name="tempbtn" IsChecked="{TemplateBinding IsChecked}" FontFamily="Segoe UI" FontSize="18.667" Content="{TemplateBinding Content}" GroupName="{TemplateBinding GroupName}"/>
      </StackPanel>
    </Grid>
</ControlTemplate>

and I use this template:

<RadioButton GroupName="CG" x:Name="_rdoBtnA" Content="A" Template="{DynamicResource RadioBtnTemplate}" IsChecked="True"/>
<RadioButton GroupName="CG" x:Name="_rdoBtnB" Content="B" Template="{DynamicResource RadioBtnTemplate}" />
<RadioButton GroupName="CG" x:Name="_rdoBtnC" Content="C" Template="{DynamicResource RadioBtnTemplate}" />

Solution

  • If we take your example as is then you have two problems which cause the problems you are seeing.

    Issue 1: Firstly your design has created six not three <RadioButton> controls. The three in the <StackPanel> and then three that are created as part of the control template. All six radio buttons are now linked as part of the GroupName="CG" group.

    As you know because they all belong to the same CG group only one of the six radio buttons can have the IsChecked property set to True. The three named controls _rdoBtnA, _rdoBtnB and _rdoBtnC are not even visible on the screen so they can never be set to True (and in the case of _rdoBtnA is promptly set to False from the XAML declared True the moment the template control is bound).

    To resolve this situation, remove the GroupName="{TemplateBinding GroupName}" from the control template definition leaving only the three top level radio buttons in the group.

    Issue 2: This is the issue I thought was the root of your problem to begin with. IsChecked={TemplateBinding IsChecked} is only OneWay binding and will not update the other way. To make the binding TwoWay you need to use the long-hand version of the binding definition, IsChecked="{Binding IsChecked, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"

    The control template now becomes this by making those two changes.

    <ControlTemplate x:Key="RadioBtnTemplate" TargetType="{x:Type RadioButton}">
        <Grid>
            <StackPanel Margin="5">
                <RadioButton Name="tempbtn" IsChecked="{Binding IsChecked, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}" FontFamily="Segoe UI" FontSize="18.667" Content="{TemplateBinding Content}" />
            </StackPanel>
        </Grid>
    </ControlTemplate>