3 Days and I still can't figure out c# reflection, please help? Trying to use a protected Type and method.

Unity’s source code for the type I need can be viewed here: DockArea.cs

I’m actually trying to use the “addTab” method metionned in DockArea.cs (Note: I cannot use GetWindow, it doesn’t allow creating multiple windows of the same type and is the only way to specify a tab placement

My code so far (for add tab):

public static void DockTab(this EditorWindow anchor, EditorWindow docked) {
    var addTab = anchor.GetType().GetMethod("AddTab", BindingFlags.Instance | BindingFlags.Public);
    object[] param = {docked};
    addTab.Invoke(docked, param);
}

And it gives the following error:

NullReferenceException: Object reference not set to an instance of an object
Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.

I think the problem may be that I’m trying to use add tab the wrong way, in EditorWindow.cs there is an example of how it’s used. Been trying for days to make it work but I have no clue what I’m doing when it comes to reflection. Tried some tutorials but I still dont get it.

Please help.

UPDATE:
Here is another piece of code I tried (based on EditorWindow.cs) but I get stuck at accessing w.rootView.allChildren and will still need the DockArea type and it still not the proper usage as it would have to run this from withing the editor window being docked… I think.

public static System.Type[] GetAllDerivedTypes(this System.AppDomain aAppDomain, System.Type aType) {
            var result = new List<System.Type>();
            var assemblies = aAppDomain.GetAssemblies();
            foreach (var assembly in assemblies) {
                var types = assembly.GetTypes();
                foreach (var type in types) {
                    if (type.IsSubclassOf(aType))
                        result.Add(type);
                }
            }
            return result.ToArray();
        }


public static void DockTab(Type desired) {
            var containerWinType = System.AppDomain.CurrentDomain.GetAllDerivedTypes(typeof(ScriptableObject)).Where(t => t.Name == "ContainerWindow").FirstOrDefault();
            if (containerWinType == null)
                throw new System.MissingMemberException("Can't find internal type 'ContainerWindow'.");

            var windows = Resources.FindObjectsOfTypeAll(containerWinType);
            foreach (var w in windows) {
                var rootviewProperty = containerWinType.GetProperty("rootView", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
                // var allChildren = rootviewProperty.get
                foreach (var view in w.rootView.allChildren)s
                    {
                        var dockArea = view as DockArea;
                        if (dockArea == null) continue;
                        if (dockArea.m_Panes.Any(pane => pane.GetType() == desired))
                        {
                            dockArea.AddTab(win);
                        }
                    }
            }
        }

Maybe its possible to override GetWindow (anothing thing I dont know how to use) to somehow prevent GetWindow from checking if a window of the requested type allready exist. If I can force it to open a new window everytime that would also work.

As Glurth already mentioned in the comment above your anchor is an EditorWindow, not a DockArea. The EditorWindow class is actually the lowest child of the hierarchy. So it’s essentially the “content” of the window. An EditorWindows, in order to be visible, need to be “placed” in a HostView. The HostView an editor window belongs to is also stored in an internal field of the EditorWindow class (m_Parent). Also as Glurth said you can never be sure what type of HostView an EditorWindow is part of until you check the type. There are the classes HostView, SplitView, DockArea, MainView (any maybe others) which build up the hierarchy of the layout of an actual single window. The top most class is usually a ContainerWindow when you have a floating window. If the view is part of the editor main window that’s another special case.

I suggest you first examine which classes you have to deal with. Manipulating the layout system of the editor is really a pain as almost every relevant class is internal. So you need a bit more reflection than those few things you currently have. Note that to use reflection in a more efficient way you want to cache the MethodInfos