Xaml资源中的泛型类型 [英] Generic Type in Xaml Resources

查看:214
本文介绍了Xaml资源中的泛型类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个像这样的通用类:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆