You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.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。

解决方案

  1. 修改反转转换器的类型校验逻辑
    放宽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();
        }
    }
    
  2. 将反转逻辑整合到多绑定转换器中
    避免在子绑定中使用转换器,直接在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 02:45:14