C# 展开可为空<;T>;在IValueConverter中获取T

C# 展开可为空<;T>;在IValueConverter中获取T,c#,type-conversion,ivalueconverter,C#,Type Conversion,Ivalueconverter,我目前正在编写一个转换器,它应该将字符串解析为long/int/short,并将值存储在绑定变量中 我遇到的问题是转换很容易,我返回一个字符串,但ConvertBack需要确切的类型(例如,将长绑定返回到短绑定将失败,而不是截断)。也就是说,我们的数据源使用所有3种数据类型(+nullable),我不想编写转换器的3个副本,并正确使用它们,我宁愿使用更智能的转换器。目前,我的代码如下所示(剩下的部分是TODO): public object ConvertBack(对象值、类型targetTyp

我目前正在编写一个转换器,它应该将字符串解析为long/int/short,并将值存储在绑定变量中

我遇到的问题是转换很容易,我返回一个字符串,但ConvertBack需要确切的类型(例如,将长绑定返回到短绑定将失败,而不是截断)。也就是说,我们的数据源使用所有3种数据类型(+nullable),我不想编写转换器的3个副本,并正确使用它们,我宁愿使用更智能的转换器。目前,我的代码如下所示(剩下的部分是TODO):

public object ConvertBack(对象值、类型targetType、对象参数、System.Globalization.CultureInfo区域性)
{
var stringValue=作为字符串的值;
var parsed=long.TryParse(stringValue,out long longValue);
if(ValueTypeHelper.IsNullableType(targetType))
{
如果(!parsed)返回null;
//TODO:这应该展开可空的null->int
//targetType=targetType.MemberType.GetType();
//编辑:工作版本如下:
targetType=Nullable.GetUnderlinegType(targetType);
}
如果(!parsed)返回0;
if(targetType.Equals(typeof(short))返回(short)longValue;
if(targetType.Equals(typeof(int))返回(int)longValue;
返回长值;
}      
不久前,从那时起,您就一直在类似的情况下使用它:

public class UniversalValueConverter : MarkupExtension, IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        // obtain the conveter for the target type
        TypeConverter converter = TypeDescriptor.GetConverter(targetType);

        try
        {
            // determine if the supplied value is of a suitable type
            if (converter.CanConvertFrom(value.GetType()))
            {
                // return the converted value
                return converter.ConvertFrom(value);
            }
            else
            {
                // try to convert from the string representation
                return converter.ConvertFrom(value.ToString());
            }
        }
        catch (Exception)
        {
            return GetDefault(targetType);
            // return DependencyProperty.UnsetValue;
            // return null;
        }

    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        TypeConverter converter = TypeDescriptor.GetConverter(targetType);
        try
        {
            // determine if the supplied value is of a suitable type
            if (converter.CanConvertFrom(value.GetType()))
            {
                // return the converted value
                return converter.ConvertFrom(value);
            }
            else
            {
                // try to convert from the string representation
                return converter.ConvertFrom(value.ToString());
            }
        }
        catch (Exception)
        {
            return GetDefault(targetType);
            // return DependencyProperty.UnsetValue;
            // return null;
        }
    }

    private static UniversalValueConverter _converter = null;

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        if (_converter == null) _converter = new UniversalValueConverter();
        return _converter;
    }

    public UniversalValueConverter()
        : base()
    {
    }

    public static object GetDefault(Type type)
    {
        if (type.IsValueType)
        {
            return Activator.CreateInstance(type);
        }
        return null;
    }
}
要在xaml中使用,请执行以下操作:

xmlns:converters="clr-namespace:MyConvertersNamespace"

....

<TextBox="{Binding Path=MyProperty, Converter={converters:UniversalValueConverter}}"/>
xmlns:converters=“clr命名空间:MyConvertersNamespace”
....

那么你的问题是什么?在您的代码中我看到:“工作版本”。它已经工作了吗?这个代码不工作了吗?不清楚您需要什么帮助。
Nullable.getUnderlinegType
已经对类型进行了展开。对于值,它只是在取消对结果的装箱时自动工作。
对象
从不包含可为空的实例,但您始终可以将其内容作为可为空的类型取消装箱。我在发布后才发现,是否最好删除该问题?
xmlns:converters="clr-namespace:MyConvertersNamespace"

....

<TextBox="{Binding Path=MyProperty, Converter={converters:UniversalValueConverter}}"/>