-
-
Notifications
You must be signed in to change notification settings - Fork 335
/
ResourceExtension.cs
119 lines (107 loc) · 3.63 KB
/
ResourceExtension.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#if PORTABLE
using Portable.Xaml;
using Portable.Xaml.Markup;
#else
using System.Xaml;
using System.Windows.Markup;
#endif
namespace Eto.Serialization.Xaml.Extensions
{
[MarkupExtensionReturnType(typeof(object))]
public class ResourceExtension : MarkupExtension
{
[ConstructorArgument("resourceName")]
public string ResourceName { get; set; }
[ConstructorArgument("assemblyName")]
public string AssemblyName { get; set; }
public ResourceExtension()
{
}
public ResourceExtension(string resourceName)
{
ResourceName = resourceName;
}
public ResourceExtension(string resourceName, string assemblyName)
{
ResourceName = resourceName;
AssemblyName = assemblyName;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
var provideValue = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
var propertyInfo = provideValue?.TargetProperty as PropertyInfo;
var contextProvider = serviceProvider.GetService(typeof(IXamlSchemaContextProvider)) as IXamlSchemaContextProvider;
if (contextProvider != null)
{
var context = contextProvider.SchemaContext as EtoXamlSchemaContext;
if (context != null && context.DesignMode)
{
// TODO: Lookup resource file using ide service so we can actually show the image or use the resource
if (propertyInfo != null)
{
if (typeof(Bitmap).IsAssignableFrom(propertyInfo.PropertyType))
return new Bitmap(24, 24, PixelFormat.Format32bppRgba);
if (typeof(Icon).IsAssignableFrom(propertyInfo.PropertyType))
return new Icon(1, new Bitmap(24, 24, PixelFormat.Format32bppRgba));
// return its current value if not a known type to handle
return propertyInfo.GetValue(provideValue.TargetObject, null);
}
return null;
}
}
Assembly assembly;
NamespaceInfo resource;
if (!string.IsNullOrEmpty(AssemblyName))
{
assembly = Assembly.Load(new AssemblyName(AssemblyName));
resource = new NamespaceInfo(ResourceName, assembly);
}
else
{
try
{
resource = new NamespaceInfo(ResourceName);
}
catch (ArgumentException)
{
var rootProvider = serviceProvider.GetService(typeof(IRootObjectProvider)) as IRootObjectProvider;
if (rootProvider == null)
throw;
assembly = rootProvider.RootObject.GetType().GetTypeInfo().Assembly;
resource = new NamespaceInfo(ResourceName, assembly);
}
}
if (propertyInfo != null && !propertyInfo.PropertyType.GetTypeInfo().IsAssignableFrom(typeof(Stream).GetTypeInfo()))
{
var converter = sc.TypeDescriptor.GetConverter(propertyInfo.PropertyType);
if (converter != null)
{
if (converter.CanConvertFrom(typeof(NamespaceInfo)))
return converter.ConvertFrom(resource);
if (converter.CanConvertFrom(typeof(Stream)))
return converter.ConvertFrom(resource.FindResource());
}
#pragma warning disable 618
var etoConverter = TypeDescriptor.GetConverter(propertyInfo.PropertyType);
if (etoConverter != null)
{
if (etoConverter.CanConvertFrom(typeof(NamespaceInfo)))
return etoConverter.ConvertFrom(resource);
if (etoConverter.CanConvertFrom(typeof(Stream)))
return etoConverter.ConvertFrom(resource.FindResource());
}
#pragma warning restore 618
var streamArgs = new [] { typeof(Stream) };
var constructor = propertyInfo.PropertyType.GetConstructor(streamArgs);
if (constructor != null)
{
return constructor.Invoke(new[] { resource.FindResource() });
}
}
Stream stream = null;
if (resource != null && resource.Assembly != null)
stream = resource.FindResource();
return stream;
}
}
}