Last active
October 4, 2016 19:29
-
-
Save robertjf/78a97240e4304b8e5bcc to your computer and use it in GitHub Desktop.
NuPicker TypeConverter for Ditto - this allows Ditto to convert from a nuPickers.Picker object to the target type
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using nuPickers; | |
| using Our.Umbraco.Ditto; | |
| using System; | |
| using System.Collections; | |
| using System.Collections.Generic; | |
| using System.ComponentModel; | |
| using System.Globalization; | |
| using System.Linq; | |
| using System.Reflection; | |
| using System.Web; | |
| using Umbraco.Core.Models; | |
| using Umbraco.Web; | |
| namespace Extensions.TypeConverters | |
| { | |
| /// <summary> | |
| /// Converts a NuPicker value into a Ditto object or string. | |
| /// </summary> | |
| /// <remarks> | |
| /// This can be used with a single type (e.g. string) or IEnumerable<>. | |
| /// | |
| /// If the target type is string, then this will return the Name(s) of each picked content node. | |
| /// Otherwise it will use Ditto to try and convert the IPublishedContent item(s) to the target type. | |
| /// | |
| /// Handles single objects as well as IEnumerable<>. | |
| /// | |
| /// E.G.: | |
| /// | |
| /// [TypeConverter(typeof(DittoNuPickerTypeConverter))] | |
| /// public IEnumerable<MyPoco> MyProperty { get; set; } | |
| /// | |
| /// // Returns a single MyPoco | |
| /// [TypeConverter(typeof(DittoNuPickerTypeConverter))] | |
| /// public MyPoco MyProperty { get; set; } | |
| /// | |
| /// // Returns a list of strings based on the Name of each item. | |
| /// [TypeConverter(typeof(DittoNuPickerTypeConverter))] | |
| /// public IEnumerable<string> MyProperty { get; set; } | |
| /// | |
| /// // Returns the Name of the first item. | |
| /// [TypeConverter(typeof(DittoNuPickerTypeConverter))] | |
| /// public string MyProperty { get; set; } | |
| /// </remarks> | |
| public class DittoNuPickerTypeConverter : TypeConverter | |
| { | |
| public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) | |
| { | |
| return typeof(Picker).IsAssignableFrom(sourceType); | |
| } | |
| public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) | |
| { | |
| MethodInfo dittoAs = typeof(Our.Umbraco.Ditto.PublishedContentExtensions) | |
| .GetMethod( | |
| "As", | |
| BindingFlags.Static | BindingFlags.Public | BindingFlags.DeclaredOnly, | |
| null, | |
| new Type[] { | |
| typeof(IPublishedContent), | |
| typeof(Action<ConvertingTypeEventArgs>), | |
| typeof(Action<ConvertedTypeEventArgs>), | |
| typeof(CultureInfo) }, | |
| null); | |
| // get type of objects to be returned in the collection | |
| Type outputItemType = context.PropertyDescriptor.PropertyType; | |
| bool isList = (outputItemType.IsGenericType && outputItemType.GetGenericTypeDefinition() == typeof(IEnumerable<>)); | |
| bool isString = isList ? | |
| typeof(string).IsAssignableFrom(outputItemType.GetGenericArguments()[0]) : | |
| outputItemType.IsAssignableFrom(typeof(string)); | |
| // create a list for the output collection | |
| // Get the list as IPublishedContent. | |
| var picker = value as Picker; | |
| var items = picker.AsPublishedContent(); | |
| if (isList) | |
| { | |
| object outputList = Activator.CreateInstance(typeof(List<>).MakeGenericType(outputItemType.GetGenericArguments()[0])); | |
| foreach (IPublishedContent inputItem in items) | |
| { | |
| if (isString) | |
| { | |
| ((IList)outputList).Add(inputItem.Name); | |
| } | |
| else { | |
| ((IList)outputList).Add( | |
| dittoAs | |
| .MakeGenericMethod(new[] { outputItemType }) | |
| .Invoke(null, new[] { inputItem, null, null, null }) | |
| ); | |
| } | |
| } | |
| return outputList; | |
| } | |
| else | |
| { | |
| if (isString) | |
| { | |
| return items.Any() ? items.FirstOrDefault().Name : null; | |
| } | |
| else | |
| { | |
| return dittoAs | |
| .MakeGenericMethod(new[] { outputItemType }) | |
| .Invoke(null, new[] { items.FirstOrDefault(), null, null, null }); | |
| } | |
| } | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hey, @JimBobSquarePants, does your technique still work? Or is there a better way now?