Click here to Skip to main content
15,880,725 members
Articles / Desktop Programming / WPF
Tip/Trick

Markup Extension for Generic classes

Rate me:
Please Sign up or sign in to vote.
5.00/5 (7 votes)
31 Jan 2015CPOL 11.6K   4   3  
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Lead
India India
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
-- There are no messages in this forum --