WPF - 单选按钮控件模板绑定 "IsChecked" 不工作
WPF - Radio button control template binding "IsChecked" not working
我有一个如下所示的控件模板,我想在用户 select 单选按钮时得到 IsChecked
属性。
但是当用户 select 单选按钮 "A" 时 IsChecked
属性 仍然显示错误。为什么?
<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>
我使用这个模板:
<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}" />
你可以这样使用它:
<StackPanel Orientation="Horizontal">
<StackPanel.Resources>
<ControlTemplate x:Key="ButtonAsSwatchTemplate">
<Border x:Name="SwatchBorder" BorderThickness="1">
<Rectangle Fill="{TemplateBinding Property=Background}" Width="15" Height="15" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="ToggleButton.IsChecked" Value="True">
<Setter TargetName="SwatchBorder" Property="BorderBrush" Value="Yellow" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</StackPanel.Resources>
<RadioButton Template="{StaticResource ButtonAsSwatchTemplate}"
GroupName="CropGuidesColourRadioButtonGroup"
IsChecked="{Binding Checked}" Margin="2" Background="Red" />
<RadioButton Template="{StaticResource ButtonAsSwatchTemplate}"
GroupName="CropGuidesColourRadioButtonGroup"
IsChecked="{Binding Checked}" Margin="2" Background="Black" />
</StackPanel>
取自Whosebug
如果我们按原样使用您的示例,那么您有两个问题导致了您所看到的问题。
问题 1:
首先,您的设计创建了 六个 而不是 三个 <RadioButton>
控件。 <StackPanel>
中的三个,然后是作为控件模板的一部分创建的三个。所有 6 个 单选按钮现在都链接为 GroupName="CG"
组的一部分。
如您所知,因为它们都属于同一个 CG
组,所以六个单选按钮中只有一个可以将 IsChecked
属性 设置为 True
。三个命名控件 _rdoBtnA
、_rdoBtnB
和 _rdoBtnC
在屏幕上什至不可见,因此它们永远不能设置为 True
(在 _rdoBtnA
在绑定模板控件时立即从声明 True
的 XAML
设置为 False
。
要解决这种情况,请从控件模板定义中删除 GroupName="{TemplateBinding GroupName}"
,只留下组中的三个顶级单选按钮。
问题 2: 我认为这个问题是您问题的根源。 IsChecked={TemplateBinding IsChecked}
只是 OneWay
绑定,不会以其他方式更新。要进行绑定 TwoWay
,您需要使用绑定定义的长手版本,IsChecked="{Binding IsChecked, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
通过进行这两项更改,控件模板现在变成了这个。
<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>
我有一个如下所示的控件模板,我想在用户 select 单选按钮时得到 IsChecked
属性。
但是当用户 select 单选按钮 "A" 时 IsChecked
属性 仍然显示错误。为什么?
<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>
我使用这个模板:
<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}" />
你可以这样使用它:
<StackPanel Orientation="Horizontal">
<StackPanel.Resources>
<ControlTemplate x:Key="ButtonAsSwatchTemplate">
<Border x:Name="SwatchBorder" BorderThickness="1">
<Rectangle Fill="{TemplateBinding Property=Background}" Width="15" Height="15" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="ToggleButton.IsChecked" Value="True">
<Setter TargetName="SwatchBorder" Property="BorderBrush" Value="Yellow" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</StackPanel.Resources>
<RadioButton Template="{StaticResource ButtonAsSwatchTemplate}"
GroupName="CropGuidesColourRadioButtonGroup"
IsChecked="{Binding Checked}" Margin="2" Background="Red" />
<RadioButton Template="{StaticResource ButtonAsSwatchTemplate}"
GroupName="CropGuidesColourRadioButtonGroup"
IsChecked="{Binding Checked}" Margin="2" Background="Black" />
</StackPanel>
取自Whosebug
如果我们按原样使用您的示例,那么您有两个问题导致了您所看到的问题。
问题 1:
首先,您的设计创建了 六个 而不是 三个 <RadioButton>
控件。 <StackPanel>
中的三个,然后是作为控件模板的一部分创建的三个。所有 6 个 单选按钮现在都链接为 GroupName="CG"
组的一部分。
如您所知,因为它们都属于同一个 CG
组,所以六个单选按钮中只有一个可以将 IsChecked
属性 设置为 True
。三个命名控件 _rdoBtnA
、_rdoBtnB
和 _rdoBtnC
在屏幕上什至不可见,因此它们永远不能设置为 True
(在 _rdoBtnA
在绑定模板控件时立即从声明 True
的 XAML
设置为 False
。
要解决这种情况,请从控件模板定义中删除 GroupName="{TemplateBinding GroupName}"
,只留下组中的三个顶级单选按钮。
问题 2: 我认为这个问题是您问题的根源。 IsChecked={TemplateBinding IsChecked}
只是 OneWay
绑定,不会以其他方式更新。要进行绑定 TwoWay
,您需要使用绑定定义的长手版本,IsChecked="{Binding IsChecked, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
通过进行这两项更改,控件模板现在变成了这个。
<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>