MAUI中带ControlTemplate和DataTemplate的RadioButton无法渲染内容
问题修复方案
1. 修复ContentPresenter不显示内容的问题
ControlTemplate中的ContentPresenter需要通过TemplateBinding绑定到RadioButton的Content属性,否则无法获取按钮内定义的内容。修改代码如下:
<ContentPresenter HeightRequest="64" Content="{TemplateBinding Content}"/>
2. 解决InvalidCastException异常
该异常多由类型不匹配引发,需检查两点:
- 确保ViewModel中
SelectedMuscleGroup的类型与MuscleGroup.Id完全一致(如均为int、Guid或字符串)。 - 移除
CheckedChanged事件绑定,避免手动处理选中状态干扰RadioButtonGroup的自动同步逻辑:
<!-- 删除CheckedChanged绑定 --> <RadioButton Value="{Binding Id}">
3. 修复RadioButtonGroup.SelectedValue绑定失效
确保ViewModel的SelectedMuscleGroup属性实现INotifyPropertyChanged接口,保证UI能感知属性变化。示例ViewModel代码:
public class ActivitiesViewModel : INotifyPropertyChanged { private int _selectedMuscleGroup; public int SelectedMuscleGroup { get => _selectedMuscleGroup; set { if (_selectedMuscleGroup != value) { _selectedMuscleGroup = value; OnPropertyChanged(); } } } public ObservableCollection<MuscleGroup> MuscleGroupList { get; set; } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
完整修改后的XAML代码
<ContentPage.BindingContext> <pages:ActivitiesViewModel/> </ContentPage.BindingContext> <ContentPage.Resources> <ControlTemplate x:Key="MuscleGroupButtonsTemplate"> <Border Stroke="{StaticResource SecondaryBrush}" StrokeThickness="1" Background="Transparent" > <Border.StrokeShape> <RoundRectangle CornerRadius="8"/> </Border.StrokeShape> <VisualStateManager.VisualStateGroups> <VisualStateGroupList> <VisualStateGroup x:Name="CheckedStates"> <VisualState x:Name="Checked"> <VisualState.Setters> <Setter Property="Background" Value="{StaticResource AccentBrush}"/> <Setter Property="Stroke" Value="{StaticResource SecondaryBrush}"/> </VisualState.Setters> </VisualState> <VisualState x:Name="Unchecked"> <VisualState.Setters> <Setter Property="Background" Value="{StaticResource NeutralBrush}"/> <Setter Property="Stroke" Value="{StaticResource SecondaryBrush}"/> </VisualState.Setters> </VisualState> </VisualStateGroup> </VisualStateGroupList> </VisualStateManager.VisualStateGroups> <ContentPresenter HeightRequest="64" Content="{TemplateBinding Content}"/> </Border> </ControlTemplate> </ContentPage.Resources> <VerticalStackLayout Spacing="12" RadioButtonGroup.GroupName="MuscleGroups" RadioButtonGroup.SelectedValue="{Binding SelectedMuscleGroup}" BindableLayout.ItemsSource="{Binding MuscleGroupList}"> <VerticalStackLayout.Resources> <Style TargetType="RadioButton"> <Setter Property="ControlTemplate" Value="{StaticResource MuscleGroupButtonsTemplate}"/> </Style> </VerticalStackLayout.Resources> <BindableLayout.ItemTemplate> <DataTemplate x:DataType="m:MuscleGroup"> <RadioButton Value="{Binding Id}"> <RadioButton.Content> <HorizontalStackLayout Margin="12,6,0,0" Spacing="8"> <Image WidthRequest="64" Aspect="AspectFit" Source="{Binding Icon}"/> <Label Style="{StaticResource Headline}" VerticalOptions="Center"> <Label.FormattedText> <FormattedString> <Span Text="{Binding Name}"/> </FormattedString> </Label.FormattedText> </Label> </HorizontalStackLayout> </RadioButton.Content> </RadioButton> </DataTemplate> </BindableLayout.ItemTemplate> </VerticalStackLayout>
内容的提问来源于stack exchange,提问作者Chuck
相关产品推荐
相关产品推荐

