解包可为空<T>以获得 T 在 IValueConverter 中



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

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

public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var stringValue = value as string;
var parsed = long.TryParse(stringValue, out long longValue);
if (ValueTypeHelper.IsNullableType(targetType))
{
if (!parsed) return null;
// TODO: this should unwrap the nullable Nullable<int> -> int
//targetType = targetType.MemberType.GetType();
// EDIT: The working version is below:
targetType = Nullable.GetUnderlyingType(targetType);
}
if (!parsed) return 0;
if (targetType.Equals(typeof(short))) return (short)longValue;
if (targetType.Equals(typeof(int))) return (int)longValue;
return 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}}"/>

最新更新