.NET MAUI多绑定中单个绑定转换器TargetType异常问题
问题
在.NET MAUI的多绑定(MultiBinding)中为其中一个绑定使用转换器时,转换器未收到正确参数。按照官方文档的用法应该可行,但实际运行时,布尔值反转转换器收到的TargetType是System.Object而非bool,触发了InvalidOperationException。普通绑定中转换器能正常收到bool类型的TargetType,多绑定中却不行。
相关代码
多绑定转换器类
public class BooleanAndConverter : IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { if (values == null || !targetType.IsAssignableFrom(typeof(bool))) { return false; } foreach (var value in values) { if (!(value is bool b)) { return false; } else if (!b) { return false; } } return true; } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { throw new NotSupportedException(); } }
布尔值反转转换器类
public class InverseBooleanConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (targetType != typeof(bool)) throw new InvalidOperationException("The target must be a boolean"); return !(bool)value; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotSupportedException(); } }
XAML使用代码
<Button Text="Passer à la ronde suivante" Command="{Binding NextRoundCommand}"> <Button.IsVisible> <MultiBinding Converter="{StaticResource BooleanAndConverter}"> <Binding Path="isGameStarted"/> <Binding Path="isPlayersPlaying" Converter="{StaticResource InvertedBoolConverter}"/> </MultiBinding> </Button.IsVisible> </Button>
原因与解决方案
原因
在MultiBinding场景下,单个绑定的转换器无法直接获取到最终目标属性的类型(这里是Button.IsVisible的bool类型)。因为MultiBinding会先处理每个子绑定的转换,此时子绑定的目标是MultiBinding的输入集合,而非最终的UI属性,所以targetType会被传递为System.Object。
解决方案
修改反转转换器的类型校验逻辑
放宽targetType的校验条件,允许targetType为object,同时确保输入值是bool类型即可:public class InverseBooleanConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { // 先校验输入值是否为bool if (!(value is bool)) throw new InvalidOperationException("The value must be a boolean"); // 允许targetType为object或bool,适配MultiBinding场景 if (targetType != typeof(bool) && targetType != typeof(object)) throw new InvalidOperationException("The target must be a boolean or object"); return !(bool)value; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotSupportedException(); } }将反转逻辑整合到多绑定转换器中
避免在子绑定中使用转换器,直接在BooleanAndConverter里处理反转逻辑,减少嵌套调用同时规避类型传递问题:public class BooleanAndConverter : IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { if (values == null || !targetType.IsAssignableFrom(typeof(bool))) { return false; } if (values.Length < 2) return false; bool isGameStarted = values[0] is bool b1 ? b1 : false; bool isPlayersPlaying = values[1] is bool b2 ? b2 : false; return isGameStarted && !isPlayersPlaying; } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { throw new NotSupportedException(); } }对应的XAML简化为:
<Button Text="Passer à la ronde suivante" Command="{Binding NextRoundCommand}"> <Button.IsVisible> <MultiBinding Converter="{StaticResource BooleanAndConverter}"> <Binding Path="isGameStarted"/> <Binding Path="isPlayersPlaying"/> </MultiBinding> </Button.IsVisible> </Button>
内容的提问来源于stack exchange,提问作者Philippe
相关产品推荐
相关产品推荐

