译:泛型类的标记扩展

译文出处:http://www.codeproject.com/Tips/871592/Markup-Extension-for-Generic-classes

标记扩展运行你再Xaml中声明泛型类。

简介:

我们经常要在Xaml中的style或DataTemplate或相似的地方使用泛型类。

然而.Net不允许在xaml中声明泛型。我们需要解决这个问题。本文提供的解决方案已经在很多案例中解决这个问题。

使用代码:

通过使用这里提供的新的扩展,你就能够在xaml中使用泛型。

<DataTemplate x:Key="genericTemplate" DataType="{ge:Generic GenericTypeName=System.Collections.Generic.KeyValuePair, GenericTypeAssemblyName=mscorlib, ArgumentType1={x:Type sys:String},ArgumentType2={x:Type sys:String}}">
            <StackPanel Orientation="Horizontal">
                <Label Background="Green" Content="{Binding Path=Key}" />
                <Label Background="Yellow" Content="{Binding Path=Value}" />
            </StackPanel>
        </DataTemplate>

在我们的标记扩展类添加下面的属性:

public string GenericTypeName { get; set; }
        public string GenericTypeAssemblyName { get; set; }
        public Type ArgumentType1 { get; set; }
        public Type ArgumentType2 { get; set; }
        public Type ArgumentType3 { get; set; }

添加ProvideValue方法:

public override object ProvideValue(IServiceProvider serviceProvider)
        {
            var genericArguments = new List<Type>();
            if(ArgumentType1 != null)
            {
                genericArguments.Add(ArgumentType1);
            }
            if(ArgumentType2 != null)
            {
                genericArguments.Add(ArgumentType2);
            }
            if(ArgumentType3 != null)
            {
                genericArguments.Add(ArgumentType3);
            }

            if(!string.IsNullOrWhiteSpace(GenericTypeName) && !string.IsNullOrWhiteSpace(GenericTypeAssemblyName) && genericArguments.Count > 1)
            {
                var genericType = Type.GetType(string.Format(_genericTypeFormat, GenericTypeName, genericArguments.Count, GenericTypeAssemblyName));
                if(genericType != null)
                {
                    var returnType = genericType.MakeGenericType(genericArguments.ToArray());
                    return returnType;
                }
            }
            return null;
        }

注意这儿有一个常量genericTypeFormat的声明如下:

private const string _genericTypeFormat="{0}`{1},{2}";

~~

posted @ 2015-02-01 21:34  IT少年  阅读(392)  评论(0编辑  收藏  举报