Beispiel #1
0
 public WPFDriverCreator(CodeDomProvider dom)
 {
     _dom = dom;
     _customNameGenerator   = new DriverElementNameGeneratorAdaptor(dom);
     _driverTypeNameManager = new DriverTypeNameManager(DriverCreatorAdapter.SelectedNamespace, DriverCreatorAdapter.TypeFullNameAndWindowDriver, DriverCreatorAdapter.TypeFullNameAndUserControlDriver);
 }
        DriverIdentifyInfo[] GetIdentifyingCandidatesCore(CodeDomProvider dom, DependencyObject rootCtrl, DependencyObject elementCtrl)
        {
            if (rootCtrl == elementCtrl)
            {
                return(new DriverIdentifyInfo[0]);
            }

            var ancestor = new List <DependencyObject>();
            var current  = VisualTreeHelper.GetParent(elementCtrl);

            while (current != null)
            {
                if (CanBeParent(current))
                {
                    ancestor.Add(current);
                }
                if (ReferenceEquals(current, rootCtrl))
                {
                    break;
                }
                current = VisualTreeHelper.GetParent(current);
            }
            if (ancestor.Count == 0)
            {
                ancestor.Add(rootCtrl);
            }

            //Fieldでたどることができる範囲を取得
            var target = elementCtrl;
            var bindingExpressionCache = new BindingExpressionCache();
            var isPerfect   = true;
            var nameSource  = string.Empty;
            var usings      = new List <string>();
            var accessPaths = new List <string>();
            var isTree      = new List <bool>();

            foreach (var e in ancestor)
            {
                //直接のフィールドに持っているか?
                var path = GetAccessPath(e, target, dom);
                if (!string.IsNullOrEmpty(path))
                {
                    //最初がフィールドで特定できた場合はその名前を使う
                    if (target == elementCtrl)
                    {
                        var sp = path.Split('.');
                        nameSource = sp.Length == 0 ? string.Empty : sp[sp.Length - 1];
                    }

                    accessPaths.Insert(0, path);
                    isTree.Insert(0, false);
                    target = e;
                }
                else
                {
                    //Treeから検索
                    var logicalForGetter = WPFUtility.GetLogicalTreeDescendants(e, false, false, 0);
                    var visualForGetter  = WPFUtility.GetVisualTreeDescendants(e, false, false, 0);
                    path = MakeCodeGetFromTree(string.Empty, logicalForGetter, visualForGetter, target, bindingExpressionCache, usings, out var nogood, out var nameFromTree);
                    if (string.IsNullOrEmpty(path))
                    {
                        return(null);
                    }
                    if (nogood)
                    {
                        isPerfect = false;
                    }
                    accessPaths.Insert(0, path);
                    isTree.Insert(0, true);
                    target = e;
                    if (string.IsNullOrEmpty(nameSource))
                    {
                        nameSource = nameFromTree;
                    }
                }
            }

            if (target != rootCtrl)
            {
                return(null);
            }

            var names = new List <string>();
            var customNameGenerator = new DriverElementNameGeneratorAdaptor(dom);
            var name = customNameGenerator.MakeDriverPropName(elementCtrl, nameSource, names);

            var  appVarCast  = string.Empty;
            bool modeDynamic = false;

            for (int i = 0; i < isTree.Count; i++)
            {
                if (isTree[i])
                {
                    if (modeDynamic)
                    {
                        if (0 < i)
                        {
                            appVarCast         = "((AppVar)" + appVarCast;
                            accessPaths[i - 1] = accessPaths[i - 1] + ")";
                        }
                    }
                    modeDynamic = false;
                }
                else
                {
                    if (!modeDynamic)
                    {
                        accessPaths[i] = "Dynamic()." + accessPaths[i];
                    }
                    modeDynamic = true;
                }
            }
            var accessPath = string.Join(".", accessPaths.ToArray());

            if (!modeDynamic)
            {
                accessPath += ".Dynamic()";
            }

            return(new[]
            {
                new DriverIdentifyInfo
                {
                    IsPerfect = isPerfect,
                    Identify = appVarCast + "Core." + accessPath,
                    DefaultName = name,
                    ExtensionUsingNamespaces = usings.ToArray(),
                    DriverTypeCandidates = GetDriverTypeCandidates(elementCtrl)
                }
            });
        }