gpt4 book ai didi

c# - xaml 中使用的通用类型的 TypeConverter

转载 作者:行者123 更新时间:2023-11-30 15:11:58 25 4
gpt4 key购买 nike

我正在研究 XAML 中声明的泛型类型的初始化成员。这是针对 (reduced) generics support在 WPF 4 和 future 的 Silverlight 中。 (我已经在 VS2010 Beta 2 中使用 x:TypeArgumentsXamlReader.Load 尝试了以下场景,但为了简单起见,我将使用 TestClassInt32 : TestClass<int> { },因为它与直接使用泛型类型具有相同的行为,但使用编译的 xaml 更容易测试今天。)


这是我正在使用的测试类型。

public class TestClass<T> {
[TypeConverter( typeof(StringListToItemsConverter) )]
public IEnumerable<T> Items { get; set; }
public TestProperty<T> Property { get; set; }
}

[TypeConverter( typeof(TestPropertyConverter) )]
public struct TestProperty<T> {
public TestProperty( T value ) : this() { Value = value; }
public T Value { get; }
}

这是示例场景。

<StackPanel>
<StackPanel.DataContext>
<test:TestClassInt32 Items="1,2,3" Property="6" />
</StackPanel.DataContext>

<TextBox Text="{Binding Property.Value}" />
<ItemsControl ItemsSource="{Binding Items}" />
</StackPanel>

当我硬编码时 typeof(int)进入这个例子的转换器,一切正常,但这种方法显然不适用于 TestClass<double>TestClass<DateTime> .问题是 TypeConverter.ConvertFrom方法无权访问目标类型,只能访问源类型。 (这在 .NET 1.0 中创建 TypeConverter 时不是问题,因为目标类型无法参数化,但现在是一个不幸的限制。)


以下是我研究过的解决此问题的方法:

  1. 使类型转换器通用;例如[TypeConverter( typeof(TestPropertyConverter<T>) )]
    • .NET 不支持属性中的类型参数
    • 拥有 TypeConverter返回一个实现 IConvertible.ToType 的中间类型, 或 has a TypeConvert that can ConvertTo the destination type
    • XAML 解析器只做一步转换:如果返回的对象不能分配给目标,它会抛出异常
    • 定义一个自定义类型描述符,它将根据实际类型返回适当的转换器
    • WPF 忽略自定义类型描述符,并且 TypeDescriptor Silverlight 中甚至不存在

以下是我为“解决”此问题而提出的备选方案:

  1. 要求目标类型嵌入到字符串中;例如"sys:Double 1,2,3"
    • 在 Silverlight 中,必须硬编码一组固定的支持类型(在 WPF 中,可以使用 IXamlTypeResolver 接口(interface)获取 "sys:Double" 对应的实际类型)
    • 编写带有类型参数的自定义标记扩展;例如"{List Type={x:Type sys:Double}, Values=1,2,3}"
    • Silverlight 不支持自定义标记扩展(它也不支持 x:Type 标记扩展,但您可以使用选项 1 中的硬编码方法)
    • 创建一个包装器类型,它接受一个类型参数并将所有通用成员重新定义为 object , 转发所有成员对底层强类型对象的访问
    • 可能,但会导致非常差的用户体验(必须强制转换以获得底层通用对象,必须仍然在 Silverlight 上使用硬编码列表作为类型参数,必须缓存成员分配直到分配类型参数,等等等;通常会失去泛型强类型的大部分好处)

很高兴听到今天或在 WPF 4 中解决此问题的任何其他想法。

最佳答案

在.NET 4 中,有一个可用的IServiceProvider,您可以通过它获得IDestinationTypeProvider。 ,然后你应该能够做你需要的。在 .NET 3 或 4 中,IProvideValueTarget服务可以给你 targetObject 和 targetProperty。从 targetProperty(PropertyInfoMethodInfo - 附加的或 DependencyProperty),您可以获取类型。

例如,要从 TypeConverterConvertFrom 中获取 IDestinationTypeProvider 服务提供者:

public override object ConvertFrom(
ITypeDescriptorContext context,
CultureInfo culture,
object value )
{
var typeProvider =
(IDestinationTypeProvider)context.GetService( typeof( IDestinationTypeProvider ) );
Type targetType = typeProvider.GetDestinationType();

// ... do stuff

return base.ConvertFrom( context, culture, value );
}

关于c# - xaml 中使用的通用类型的 TypeConverter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1723263/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com