Xaml资源中的泛型类型 [英] Generic Type in Xaml Resources
问题描述
我有一个像这样的通用类:
I have a generic class like this:
public class GenericClass<T> where T : class
{
public GenericClass()
{
}
}
我希望此类作为资源保存在Window或UserControl中。然后我需要一个Xaml的GenericTypeExtension,例如 https://stackoverflow.com/a/5403397/376086 , :
And I want this class to hold as a resource in a Window or UserControl. Then I need a GenericTypeExtension for Xaml like this https://stackoverflow.com/a/5403397/376086 which I copied so:
[ContentProperty("TypeArguments")]
public class GenericTypeExtension : MarkupExtension
{
private Collection<Type> _typeArguments = new Collection<Type>();
public Collection<Type> TypeArguments
{
get { return _typeArguments; }
}
// generic:List`1
private string baseTypeName;
public string BaseTypeName
{
get { return baseTypeName; }
set { baseTypeName = value; }
}
public GenericTypeExtension()
{
}
public GenericTypeExtension(string baseTypeName)
{
this.baseTypeName = baseTypeName;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
if (string.IsNullOrEmpty(baseTypeName))
throw new ArgumentNullException("BaseTypeName");
string[] baseTypeArray = baseTypeName.Split(':');
if (baseTypeArray.Length != 2)
throw new ArgumentException("BaseTypeName");
if (TypeArguments.Count == 0)
throw new ArgumentException("TypeArguments");
IXamlNamespaceResolver nameResolver =
serviceProvider.GetService(typeof(IXamlTypeResolver)) as IXamlNamespaceResolver;
IXamlSchemaContextProvider schemeContextProvider =
serviceProvider.GetService(typeof(IXamlSchemaContextProvider)) as IXamlSchemaContextProvider;
if (nameResolver == null || schemeContextProvider == null)
{
IRootObjectProvider rootObjectProvider =
serviceProvider.GetService(typeof(IRootObjectProvider)) as IRootObjectProvider;
if (rootObjectProvider as DependencyObject != null &&
!DesignerProperties.GetIsInDesignMode(rootObjectProvider as DependencyObject))
throw new Exception("This Generic markup extension requires these services");
else
return null;
}
XamlTypeName xamlTypeName = new XamlTypeName(nameResolver.GetNamespace(baseTypeArray[0]), baseTypeArray[1]);
Type genericType = schemeContextProvider.SchemaContext.GetXamlType(xamlTypeName).UnderlyingType;
Type[] typeArguments = TypeArguments.ToArray();
return Activator.CreateInstance(genericType.MakeGenericType(typeArguments));
}
}
但是为什么我这样做时会得到XamlParseException :
But why do I get a XamlParseException when I do this:
<Window x:Class="GenericXaml.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:genericXaml="clr-namespace:GenericXaml"
xmlns:system="clr-namespace:System;assembly=mscorlib"
Title="MainWindow"
Width="525"
Height="350">
<Window.Resources>
<genericXaml:GenericTypeExtension BaseTypeName="genericXaml:GenericClass`1" x:Key="hanswurst">
<x:Type TypeName="system:String" />
</genericXaml:GenericTypeExtension>
</Window.Resources>
<Grid />
</Window>
例外在这里:
The Exception is here:
内部异常的文本为:
The Text of the Inner Exception is:
我在做什么错了?
更新:
它也无法使用:
Update: It also doesn't work with:
<genericXaml:GenericTypeExtension BaseTypeName="generic:List`1" x:Key="kdid">
<x:Type TypeName="system:String"/>
</genericXaml:GenericTypeExtension>
推荐答案
发生的事情是WPF尝试分配您的标记扩展名值添加到资源
属性,而不是将一项添加到字典中。这可以通过以下方式轻松解决:
What's happening is that WPF attempts to assign your markup extension's value to the Resources
property, instead of adding an item to the dictionary. This can be easily solved by:
<Window.Resources>
<ResourceDictionary>
<genericXaml:GenericTypeExtension BaseTypeName="genericXaml:GenericClass`1" x:Key="hanswurst">
<x:Type TypeName="system:String" />
</genericXaml:GenericTypeExtension>
</ResourceDictionary>
</Window.Resources>
这篇关于Xaml资源中的泛型类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!