Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Markup Extension for Generic classes

0.00/5 (No votes)
31 Jan 2015 2  
Markup Extension that allows you to declare Generic classes in Xaml

Introduction

Most of us would have needed to use Generic types in Xaml, be it in Style or DataTemplate or some similar places. Since .Net does not allow Generic type to be declared in Xaml, we need this work around. While solution provided here far from perfect, it still solves problems for most usecases.

Using the code

 

Using the new Extension provided here, you would be able to use Generic types in Xaml as shown below

 

XML
       <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>

In your markup extension class (GenericExtension) add following properties:

C#
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; }

And add implementation of ProvideValue method:

C#
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;
}

Notice that there a constant _genericTypeFormat, which is declared as follows:

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

Attachment contains basic usage and GenericExtension itself.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here