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

VS2022中WPF的IValueConverter无法校验targetType为Visibility的问题

问题:VS2022中IValueConverter的targetType判断失效问题

我有一个将null转换为Visible的IValueConverter,代码如下:

public class InverseNullToVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter,
        System.Globalization.CultureInfo culture)
    {
        if (targetType != typeof(System.Windows.Visibility))
            throw new InvalidOperationException("The target must be a Visibility");
        
        if (value == null)
            return Visibility.Visible;

        return Visibility.Collapsed;
    }

    public object ConvertBack(object value, Type targetType, object parameter,
        System.Globalization.CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

该代码在Visual Studio 2019中运行正常,但升级到Visual Studio 2022后,所有使用该转换器的地方都出现错误,上述代码中的第一个if判断始终返回true。我使用的是.NET Framework 4.7.2,收到的错误码为XDG0066,错误信息为抛出的"The target must be a Visibility"。

转换器的使用示例如下:

<Rectangle x:Name="Back" Fill="{TemplateBinding Background}" Visibility="{TemplateBinding ImageBack, Converter={StaticResource InverseNullToVisibilityConverter}}"/>

请问为何VS2022中if (targetType != typeof(System.Windows.Visibility))判断失效?该如何修改才能正常工作?


原因与解决方案

原因

VS2022针对.NET Framework项目的XAML编译器进行了更新,在处理TemplateBinding时,传递给Convert方法的targetType会被包装为**可空类型(Nullable<Visibility>)**或通过类型包装器传递,直接使用typeof(System.Windows.Visibility)做严格相等判断会不匹配,导致条件始终为true,触发异常。而VS2019的旧版编译器没有这个行为差异,因此代码能正常运行。

修改方案

需要调整类型判断逻辑,兼容可空类型或类型包装的情况,有两种可行方案:

方案1:兼容可空类型

先获取可空类型的底层实际类型,再做判断:

var actualTargetType = Nullable.GetUnderlyingType(targetType) ?? targetType;
if (actualTargetType != typeof(System.Windows.Visibility))
    throw new InvalidOperationException("The target must be a Visibility");

方案2:使用类型可分配性判断

利用Type.IsAssignableFrom判断目标类型是否兼容Visibility:

if (!typeof(System.Windows.Visibility).IsAssignableFrom(targetType))
    throw new InvalidOperationException("The target must be a Visibility");

最终完整代码

推荐使用方案1,因为能明确处理可空类型场景,修改后的完整代码如下:

public class InverseNullToVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter,
        System.Globalization.CultureInfo culture)
    {
        var actualTargetType = Nullable.GetUnderlyingType(targetType) ?? targetType;
        if (actualTargetType != typeof(System.Windows.Visibility))
            throw new InvalidOperationException("The target must be a Visibility");
        
        return value == null ? Visibility.Visible : Visibility.Collapsed;
    }

    public object ConvertBack(object value, Type targetType, object parameter,
        System.Globalization.CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

修改后,转换器在VS2019和VS2022中都能正常工作,不会再触发XDG0066错误。


内容的提问来源于stack exchange,提问作者Kevin Uchiha

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 19:20:26