using System; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Ink; using System.Linq; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using System.Collections.Generic; using System.Windows.Markup; using System.Diagnostics; namespace TypeLoaderImpl { /// /// Provides functionality to load any type with its class name, namespace and assembly-name within the Silverlight environment. /// /// /// The Type.GetType method is different in Silverlight than in the standard .NET runtime. In Silverlight we have to provide the /// fully qualified assembly name to get a type in a custom assembly. Only build in controls or types in the same assembly are /// excluded from this rule. Full qualified assembly name means a syntax like the following: /// MyComponent.MyType, MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=4bec85d7bec6698f. /// This class uses the XamlReader capability to resolve type during parsing a xaml-string. While this is a little time consuming /// the TypeLoader maintains a cache to get types faster. /// public static class TypeLoader { // cache for resolved type private static Dictionary cache = new Dictionary(); /// /// Gets the System.Type with the specified name, name space and assembly name. /// /// The class name without namespace. /// The name space /// The name of the assembly containing the type. /// The type matching the provided parameters or null if not found. [DebuggerStepThrough()] public static Type GetType(string className, string nameSpace, string assemblyName) { // check if (string.IsNullOrWhiteSpace(nameSpace)) return null; string xamlNamespace = string.Format("clr-namespace:{0}", nameSpace); // assembly name is optional if (!string.IsNullOrWhiteSpace(nameSpace)) xamlNamespace += string.Format(";assembly={0}", assemblyName); return GetType(className, xamlNamespace); } /// /// Gets the System.Type with the specified name. /// This method overload can be used for: /// 1. core controls such as Button, Grid, ListBox, etc. without specifying the namespace or assembly name. /// 2. with the qualified assembly name of the type without version and public key token like this: "MyNamespace.MyType, MyAssembly". /// /// Pure class name of Core Controls such as Button, Grid, ListBox, etc. /// The type matching the provided parameters or null if not found. [DebuggerStepThrough()] public static Type GetType(string className) { if (className != null && className.Contains(",")) { string[] qualifiedNameParts = className.Split(','); if (qualifiedNameParts.Length == 2) { string[] fullClassNameParts = qualifiedNameParts[0].Split('.'); if (fullClassNameParts.Length > 0) { // classname string newClassName = fullClassNameParts.Last().Trim(); // namespace string nameSpace = ""; for (int i = 0; i < fullClassNameParts.Length - 1; i++) { nameSpace += fullClassNameParts[i] + "."; } nameSpace = nameSpace.TrimEnd('.'); string assemblyName = qualifiedNameParts[1].Trim(); return GetType(newClassName, nameSpace, assemblyName); } } } return GetType(className, ""); } /// /// Gets the System.Type with the specified name. The xaml namespace specifies the namespace and assembly name in the same syntax as in xaml. /// /// The class name without namespace. /// /// The xaml namespace. This is the same syntax as used in XAML syntax. /// Example: "clr-namespace:MyComponent.SubNamespace;assembly=MyAssemblyName /// /// The type matching the provided parameters or null if not found. [DebuggerStepThrough()] public static Type GetType(string className, string xamlNamespace) { // check input if (string.IsNullOrWhiteSpace(className)) return null; if (className.Contains(".")) throw new ArgumentException("className must not include the namespace. Please provide namespace with separate parameter."); // check if type is already in cache string key = xamlNamespace + "&" + className; if (cache.ContainsKey(key)) return cache[key]; lock (cache) { try { // check again because another thread might be faster and has already created the cache-entry if (cache.ContainsKey(key)) return cache[key]; // create xaml with a simply Style element and set the TargetType property with the provided type name string xaml = "