MAUI转换器抛出异常:绑定AutomationProperties时导航失败
MAUI中IsStringNotNullOrWhiteSpaceConverter绑定AutomationProperties.IsInAccessibleTree引发导航异常的解决办法
问题背景
要实现的逻辑是:根据LeftAccessibilityName是否非空非空白,控制UI元素是否出现在辅助功能树里。于是把AutomationProperties.IsInAccessibleTree绑定到这个属性,用MAUI Community Toolkit里的IsStringNotNullOrWhiteSpaceConverter把字符串转成布尔值。但每次导航到包含该控件的页面时,都会触发导航异常,日志如下:
Id = 1, Status = RanToCompletion, Method = {null}, Result = NavigationResult { Success = False, Exception = Prism.Navigation.NavigationException: An error occurred while resolving the page. This is most likely the result of invalid XAML or other type initialization exception ---> System.Exception: Unable to create Page 'RegistrationUserDetailsPage'. ---> Prism.Ioc.ContainerResolutionException: An unexpected error occurred while resolving 'RegistrationUserDetailsPage' ---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.ArgumentException: targetType needs to be assignable from System.Boolean. (Parameter 'targetType')
移除转换器后导航恢复正常,试过用资源字典声明转换器也没用,只有在MauiProgram.cs里配置.UseMauiCommunityToolkit(x => x.SetShouldSuppressExceptionsInConverters(true)),才能绕过这个问题。
相关XAML代码:
<Grid xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:converters="http://schemas.microsoft.com/dotnet/2022/maui/toolkit" x:Name="This" ColumnDefinitions="*"> <ContentView Grid.Column="0" AutomationProperties.IsInAccessibleTree="{Binding LeftAccessibilityName, Converter={converters:IsStringNotNullOrWhiteSpaceConverter}, Source={x:Reference This}}" /> </Grid>
原因分析
核心问题是类型不匹配:
AutomationProperties.IsInAccessibleTree的属性类型是bool?(可空布尔值)- 而
IsStringNotNullOrWhiteSpaceConverter的Convert方法返回的是bool(非可空布尔值)
当绑定系统尝试把转换器返回的bool值赋值给bool?类型的属性时,转换器的目标类型检查会报错,因为System.Boolean(非可空)和System.Boolean?(可空)不是直接可赋值的类型,触发了ArgumentException。开启抑制转换器异常的配置后,框架会忽略这个错误,所以页面能正常加载,但这只是治标不治本的办法。
解决方案
自定义适配可空布尔值的转换器
写一个返回bool?类型的转换器,匹配目标属性的类型:
using System.Globalization; using Microsoft.Maui.Controls; namespace YourAppNamespace.Converters; public class StringToNullableBoolConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { // 检查输入是否为字符串,判断是否非空非空白,返回可空布尔值 return value is string str && !string.IsNullOrWhiteSpace(str); } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { // 因为是单向绑定,不需要实现反向转换 throw new NotImplementedException("反向转换未实现"); } }
然后在XAML中引用这个自定义转换器:
<!-- 先在页面资源中声明转换器 --> <Grid.Resources> <converters:StringToNullableBoolConverter x:Key="StringToNullableBoolConverter" /> </Grid.Resources> <!-- 使用自定义转换器绑定 --> <ContentView Grid.Column="0" AutomationProperties.IsInAccessibleTree="{Binding LeftAccessibilityName, Converter={StaticResource StringToNullableBoolConverter}, Source={x:Reference This}}" />
这样转换器返回的bool?类型和目标属性类型完全匹配,绑定过程不会再抛出类型不匹配的异常,导航也能正常进行,不需要依赖抑制异常的配置。
内容的提问来源于stack exchange,提问作者BruceTheBrick
相关产品推荐
相关产品推荐

