private void CreateDriverInfoFindFromControlTree(
            int mdiChildrenIndex,
            Control root,
            Control target,
            DriverInfo <Control> driverInfo,
            IList <ControlAndDefine> controlAndDefines,
            IList <Control> mappedControls,
            IList <string> names,
            int[] controlTreeIndecies,
            string fileName)
        {
            var next = new List <int>(controlTreeIndecies)
            {
                0
            };

            for (int i = 0; i < target.Controls.Count; i++)
            {
                next[next.Count - 1] = i;
                var ctrl = target.Controls[i];

                //すでにマップされているかチェック
                if (CollectionUtility.HasReference(mappedControls, ctrl))
                {
                    continue;
                }

                //コントロールドライバ検索
                var driver = DriverCreatorUtils.GetDriverTypeFullName(ctrl, DriverCreatorAdapter.TypeFullNameAndControlDriver);
                if (!string.IsNullOrEmpty(driver))
                {
                    var name      = _customNameGenerator.MakeDriverPropName(ctrl, string.Empty, names);
                    var typeName  = DriverCreatorUtils.GetTypeName(driver);
                    var nameSpace = DriverCreatorUtils.GetTypeNamespace(driver);
                    var getter    = MakeCodeGetFromControls(mdiChildrenIndex, root, ctrl.GetType(), next, out var nogood);

                    DriverCreatorAdapter.AddCodeLineSelectInfo(fileName, getter, ctrl);

                    var code = $"public {typeName} {name} => new {typeName}({getter});";
                    if (nogood)
                    {
                        code += $" {TodoComment}";
                    }
                    controlAndDefines.Add(new ControlAndDefine(ctrl, code));
                    mappedControls.Add(ctrl);
                    if (!driverInfo.Usings.Contains(nameSpace))
                    {
                        driverInfo.Usings.Add(nameSpace);
                    }
                }
                else if (!(ctrl is UserControl))
                {
                    //さらに下の階層を検索
                    CreateDriverInfoFindFromControlTree(mdiChildrenIndex, root, ctrl, driverInfo, controlAndDefines, mappedControls, names, next.ToArray(), fileName);
                }
            }
        }
        private void GetAllFormAndUserControl(bool isControlTreeOnly, Control control, IDictionary <Type, Control> targets, IList <Type> getFromControlTreeOnly, IList <Control> recursiveCheck)
        {
            if (control == null)
            {
                return;
            }

            //再帰チェック
            if (CollectionUtility.HasReference(recursiveCheck, control))
            {
                return;
            }
            recursiveCheck.Add(control);

            if ((control is Form) || (control is UserControl))
            {
                targets[control.GetType()] = control;
                if (isControlTreeOnly)
                {
                    getFromControlTreeOnly.Add(control.GetType());
                }

                //Form, UserControlの時はメンバも見る
                foreach (var field in GetFields(control))
                {
                    GetAllFormAndUserControl(false, field.Control, targets, getFromControlTreeOnly, recursiveCheck);
                }
            }

            foreach (Control ctrl in control.Controls)
            {
                GetAllFormAndUserControl(true, ctrl, targets, getFromControlTreeOnly, recursiveCheck);
            }

            //MDI対応
            foreach (var form in (control as Form)?.MdiChildren ?? new Form[0])
            {
                GetAllFormAndUserControl(true, form, targets, getFromControlTreeOnly, recursiveCheck);
            }
        }
        private DriverInfo <Control> CreateDriverInfo(Control targetControl, string fileName)
        {
            var driverInfo = new DriverInfo <Control>(targetControl);

            var mappedControls = new List <Control>();
            var names          = new List <string>();
            var ancesters      = WindowUtilityInTarget.GetAncesters(targetControl);

            var controlAndDefines = new List <ControlAndDefine>();

            //フィールドから検索
            foreach (var field in GetFields(targetControl))
            {
                //たまにフィールドに親を持っているのがいるのではじく
                if (CollectionUtility.HasReference(ancesters, field.Control))
                {
                    continue;
                }

                //不正なフィールド名のものは取得できない
                if (!_dom.IsValidIdentifier(field.Name))
                {
                    continue;
                }

                //すでにマップされているかチェック
                if (CollectionUtility.HasReference(mappedControls, field.Control))
                {
                    continue;
                }

                //コントロールドライバ
                var driver = DriverCreatorUtils.GetDriverTypeFullName(field.Control, DriverCreatorAdapter.TypeFullNameAndControlDriver);
                if (!string.IsNullOrEmpty(driver))
                {
                    mappedControls.Add(field.Control);
                    var typeName  = DriverCreatorUtils.GetTypeName(driver);
                    var nameSpace = DriverCreatorUtils.GetTypeNamespace(driver);
                    var name      = _customNameGenerator.MakeDriverPropName(field.Control, field.Name, names);
                    var key       = $"Core.Dynamic().{field.Name}";
                    controlAndDefines.Add(new ControlAndDefine(field.Control, $"public {typeName} {name} => new {typeName}({key});"));
                    DriverCreatorAdapter.AddCodeLineSelectInfo(fileName, key, field.Control);
                    if (!driverInfo.Usings.Contains(nameSpace))
                    {
                        driverInfo.Usings.Add(nameSpace);
                    }
                }
                //ユーザーコントロールドライバ
                else if (field.Control is UserControl)
                {
                    mappedControls.Add(field.Control);
                    var name = _customNameGenerator.MakeDriverPropName(field.Control, field.Name, names);
                    names.Add(name);
                    var typeName = _driverTypeNameManager.MakeDriverType(field.Control, out var nameSpace);
                    if (!string.IsNullOrEmpty(nameSpace) && (nameSpace != DriverCreatorAdapter.SelectedNamespace) && !driverInfo.Usings.Contains(nameSpace))
                    {
                        driverInfo.Usings.Add(nameSpace);
                    }
                    var key = $"new WindowControl(Core.Dynamic().{field.Name}";
                    controlAndDefines.Add(new ControlAndDefine(field.Control, $"public {typeName} {name} => new {typeName}({key}));"));
                    DriverCreatorAdapter.AddCodeLineSelectInfo(fileName, key, field.Control);
                }
            }

            //フィールド上に現れないオブジェクトを検索
            CreateDriverInfoFindFromControlTree(-1, targetControl, targetControl, driverInfo, controlAndDefines, mappedControls, names, new int[0], fileName);

            //Sortのロジックがイマイチわかっていない。念のため
            try
            {
                // タブオーダー順のコントロールリスト取得
                var controlList = GetTabOrderChildControls(targetControl);

                // フィールドをタブオーダーでソート
                controlAndDefines.Sort((l, r) => controlList.IndexOf(l.Control) - controlList.IndexOf(r.Control));
            }
            catch { }

            foreach (var e in controlAndDefines)
            {
                driverInfo.Members.Add(e.Define);
            }

            return(driverInfo);
        }