.NET MAUI 7样式设置时出现调用目标抛出异常问题排查
问题场景
我自行开发了一个自定义控件,包含如下属性:
public TextAlignment HorizontalIconAlignment { get { return (TextAlignment)GetValue(HorizontalIconAlignmentProperty); } set { SetValue(HorizontalIconAlignmentProperty, value); } } public static readonly BindableProperty HorizontalIconAlignmentProperty = BindableProperty.Create("HorizontalTextAlignment", typeof(TextAlignment), typeof(DuoToneIcon), TextAlignment.Start, propertyChanged: OnHorizontalIconAlignmentPropertyChanged); private static void OnHorizontalIconAlignmentPropertyChanged(BindableObject bindable, object oldValue, object newValue) { var control = (myControl)bindable; control.Label.HorizontalTextAlignment = (TextAlignment)newValue; }
直接在控件上设置该属性时可正常使用:
<local:myControl Text="Something" HorizontalIconAlignment="Center" PrimaryColor="red" />
为避免重复设置,我将其加入Style.xaml的样式中:
<Style TargetType="local:myControl"> <Setter Property="PrimaryColor" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource Gray900}}" /> </Style>
此时样式正常工作,但添加HorizontalIconAlignment设置后出现异常:
<Style TargetType="local:myControl"> <Setter Property="PrimaryColor" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource Gray900}}" /> <Setter Property="HorizontalIconAlignment" Value="Center" /> </Style>
异常信息:
Microsoft.Maui.Controls.Xaml.XamlParseException: 'Position 10:37. Type converter failed: Exception has been thrown by the target of an invocation.'
XmlInfo: Resources/Styles/Styles.xaml
问题原因及解决方案
你遇到的问题是依赖属性创建时的配置错误,具体有两处:
依赖属性名称不匹配:
BindableProperty.Create的第一个参数是依赖属性对应的CLR属性名称,你写的是"HorizontalTextAlignment",但实际CLR属性名是HorizontalIconAlignment。样式系统会通过这个名称匹配依赖属性,名称不匹配会导致类型转换器无法正确解析属性,抛出异常。所有者类型错误:
BindableProperty.Create的第三个参数是依赖属性所属的控件类型,你写的是typeof(DuoToneIcon),但这个属性属于myControl,应该改为typeof(myControl)。
修正后的代码:
public TextAlignment HorizontalIconAlignment { get { return (TextAlignment)GetValue(HorizontalIconAlignmentProperty); } set { SetValue(HorizontalIconAlignmentProperty, value); } } public static readonly BindableProperty HorizontalIconAlignmentProperty = BindableProperty.Create( nameof(HorizontalIconAlignment), // 使用nameof避免硬编码错误 typeof(TextAlignment), typeof(myControl), TextAlignment.Start, propertyChanged: OnHorizontalIconAlignmentPropertyChanged); private static void OnHorizontalIconAlignmentPropertyChanged(BindableObject bindable, object oldValue, object newValue) { var control = (myControl)bindable; control.Label.HorizontalTextAlignment = (TextAlignment)newValue; }
建议使用nameof(HorizontalIconAlignment)代替硬编码字符串,避免后续属性名修改时出现不一致问题。
内容的提问来源于stack exchange,提问作者Imran Sh

