Juan Pablo Gomez
Juan Pablo Gomez

Reputation: 5524

c# Generic Converter for

I have a converter that allow me to convert between SelectedItems and a Generic List<MyType>

public class SelectedTiposDocsToList : BaseConverter, IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var Selecteditems = value as IList;
        List<MyType> MyTypeList = Selecteditems.Cast<MyType>().ToList();
        return MyTypeList;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
} 

Now this is a common task for me and want to extend this class to allow a generic type is this something like this maybe ?

public class SelectedTiposDocsToList : BaseConverter, IValueConverter
{
    public object Convert<T>(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var Selecteditems = value as IList;
        List<T> MyTypeList = Selecteditems.Cast<T>().ToList();
        return MyTypeList;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
} 

Is this Possible ? If Yes.. How to use thsi type of converter on XAML ?

Upvotes: 5

Views: 2137

Answers (2)

BradleyDotNET
BradleyDotNET

Reputation: 61339

No, this would not be a valid implementation of IValueConverter. However, you can pass a type on the parameter:

{Binding MyVariable, Converter={StaticResource SelectedTiposDocsToList}, ConverterParameter={x:Type local:MyType}}

Then you would use Select with the Convert.ChangeType method: MSDN

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
    var Selecteditems = value as IList;
    var MyTypeList = Selecteditems.Cast<object>().Select((i) => System.Convert.ChangeType(i, parameter as Type)).ToList();
    return MyTypeList;
}

Verified as compiling on VS 2013.

Upvotes: 4

Tim S.
Tim S.

Reputation: 56536

This can be done with a bit of reflection: Type.MakeGenericType to get the type, Activator.CreateInstance to invoke the right constructor, and MethodInfo.MakeGenericMethod to give the parameter to Cast.

public Type ConvertType { get; set; }
public object Convert(object value, Type targetType, object parameter,
                      System.Globalization.CultureInfo culture)
{
    var type = typeof(List<>).MakeGenericType(ConvertType);
    var methodInfo = typeof(Enumerable).GetMethod("Cast");
    var genericMethod = methodInfo.MakeGenericMethod(ConvertType);
    var convertTypeList = Activator.CreateInstance(type,
                    genericMethod.Invoke(null, new[] { value }));
    return convertTypeList;
}

You can specify the type in XAML with x:Type.

<myns:SelectedTiposDocsToList x:Key="Conv" ConvertType="{x:Type myns:MyType}" />

Upvotes: 1

Related Questions