WPF - General IValueConverter?

I need to convert several different objects, and I would like to avoid writing a converter class for each of them. Each of the objects inherits from the base class, and I need to use Id to get the description (which is processed in my call to my CacheManager).

For each class (I have about 30 of them) I have the following code:

object IValueConverter.Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { Dictionary<int, string> codes = CacheManager.CodeLookup<CourtEventCode>(); int id = 0; string result = string.Empty; if (int.TryParse(value.ToString(), out id) && id > 0) { if (codes.ContainsKey(id)) { result = codes[id]; } else { result = "Unknown"; } } return result; } 

In the above example, CourtEventCode is a converter for this single class. Is there a way to get this class from input targetType IValueConverter.Convert instead of essentially copying and pasting this class two dozen times?

Thanks in advance,
Sonny

+4
source share
2 answers

Yes, you can call CacheManager.CodeLookup using reflection.

Based on the code you shared, it will be something like this:

 Type containingType = typeof (CacheManager); var method = containingType.GetMethod("CodeLookup", BindingFlags.Static | BindingFlags.Public, null, new Type[0], new ParameterModifier[0]); var concreteMethod = method.MakeGenericMethod(targetType); Dictionary<string,int> codes = (Dictionary<string,int>)concreteMethod.Invoke(null, null); 

You might want to cache a concreteMethod instance for each targetType, if you use a lot method, reflection can be expensive in terms of performance.

Edit : when a method is overloaded to fit a specific overload; use the GetMethod overload, which allows you to specify the exact parameters, skipping in an empty array (since the overload you want to call has no parameters). Sample code updated.

+1
source

This answer is an alternative to generics.

You can use the code generator to speed up the process by creating all classes in one go. Create an empty "TT" file (you will not see it in the list of new items, just enter the extension manually). Click OK in the warning dialog box and paste it into it. Play from there until the output file looks right. The output file will be recreated every time a TT file is saved.

 // The code in this CS file is auto-generated. using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Data; namespace WpfApplication { <# string[] classes = new string[] {"CourtEventCode", "SomeOtherCode", "WhatElseIsThere"}; foreach (string classname in classes) { #> public class <#= classname #>ValueConverter : IValueConverter { object IValueConverter.Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { Dictionary<int, string> codes = CacheManager.CodeLookup< <#= classname #> >(); int id = 0; string result = string.Empty; if (int.TryParse(value.ToString(), out id) && id > 0) { if (codes.ContainsKey(id)) { result = codes[id]; } else { result = "Unknown"; } } return result; } // Implement the rest of IValueConverter } <# } #> } 
+2
source

All Articles