void AddItemToStackLayout(ClassAndSubclasses parentClass, int level) { // If assembly is not Xamarin.Forms, display full name. string name = parentClass.IsXamarinForms ? parentClass.Type.Name : parentClass.Type.FullName; TypeInfo typeInfo = parentClass.Type.GetTypeInfo(); // If generic, display angle brackets and parameters. if (typeInfo.IsGenericType) { Type[] parameters = typeInfo.GenericTypeParameters; name = name.Substring(0, name.Length - 2); name += "<"; for (int i = 0; i < parameters.Length; i++) { name += parameters[i].Name; if (i < parameters.Length - 1) { name += ", "; } } name += ">"; } // Create Label and add to StackLayout. Label label = new Label { Text = String.Format("{0}{1}", new string(' ', 4 * level), name), TextColor = parentClass.Type.GetTypeInfo().IsAbstract ? Color.Accent : Color.Default }; stackLayout.Children.Add(label); // Now display nested types. foreach (ClassAndSubclasses subclass in parentClass.Subclasses) { AddItemToStackLayout(subclass, level + 1); } }
public PlatformClassHierarchyPage() { InitializeComponent(); List<TypeInformation> classList = new List<TypeInformation>(); string[] assemblyNames = Device.OnPlatform( iOS: new string[] { "Xamarin.Forms.Platform.iOS" }, Android: new string[] { "Xamarin.Forms.Platform.Android" }, WinPhone: new string[] { "Xamarin.Forms.Platform.UAP", "Xamarin.Forms.Platform.WinRT", "Xamarin.Forms.Platform.WinRT.Tablet", "Xamarin.Forms.Platform.WinRT.Phone" } ); foreach (string assemblyName in assemblyNames) { try { Assembly assembly = Assembly.Load(new AssemblyName(assemblyName)); GetPublicTypes(assembly, classList); } catch { } } // Ensure that all classes have a base type in the list. // (i.e., add Attribute, ValueType, Enum, EventArgs, etc.) int index = 0; // Watch out! Loops through expanding classList! do { // Get a child type from the list. TypeInformation childType = classList[index]; if (childType.Type != typeof(Object)) { bool hasBaseType = false; // Loop through the list looking for a base type. foreach (TypeInformation parentType in classList) { if (childType.IsDerivedDirectlyFrom(parentType.Type)) { hasBaseType = true; } } // If there's no base type, add it. if (!hasBaseType && childType.BaseType != typeof(Object)) { classList.Add(new TypeInformation(childType.BaseType, false)); } } index++; } while (index < classList.Count); // Now sort the list. classList.Sort((t1, t2) => { return String.Compare(t1.Type.Name, t2.Type.Name); }); // Start the display with System.Object. ClassAndSubclasses rootClass = new ClassAndSubclasses(typeof(Object), false); // Recursive method to build the hierarchy tree. AddChildrenToParent(rootClass, classList); // Recursive method for adding items to StackLayout. AddItemToStackLayout(rootClass, 0); }
void AddChildrenToParent(ClassAndSubclasses parentClass, List<TypeInformation> classList) { foreach (TypeInformation typeInformation in classList) { if (typeInformation.IsDerivedDirectlyFrom(parentClass.Type)) { ClassAndSubclasses subClass = new ClassAndSubclasses(typeInformation.Type, typeInformation.IsXamarinForms); parentClass.Subclasses.Add(subClass); AddChildrenToParent(subClass, classList); } } }