private XamlDomObject CreateXamlDom(XDocument xDocument)
        {
            _document = xDocument;
            var schemaContext = new XamlSchemaContext();

            var rootObjectsTag = GetElementWithMatchingAttribute(xDocument.Root.Element(XName.Get("data")), "key", "IBDocument.RootObjects");
            var windowTag      = GetElementWithMatchingAttribute(rootObjectsTag, "class", "IBUIWindow");

            XamlDomObject rootDomObject;

            if (windowTag != null)
            {
                rootDomObject = ViewHandler.CreateObject(windowTag, schemaContext)[0];
            }
            else // No window so there's one or more views
            {
                rootDomObject = new XamlDomObject(schemaContext.GetXamlType(typeof(UserControl)));
                var canvas = new XamlDomObject(schemaContext.GetXamlType(typeof(Canvas)));

                // TODO: We should make the DOM handle string based lookup of content here correctly.  Null refs currently
                rootDomObject.MemberNodes.Add(
                    new XamlDomMember(schemaContext.GetXamlType(typeof(UserControl)).ContentProperty, canvas));
                var canvasChildrenMember = new XamlDomMember(schemaContext.GetXamlType(typeof(Canvas)).ContentProperty);
                canvas.MemberNodes.Add(canvasChildrenMember);

                foreach (var viewTag in from objectTag in rootObjectsTag.Elements()
                         let attriNode = objectTag.Attribute(XName.Get("class"))
                                         where attriNode != null
                                         select objectTag)
                {
                    if (viewTag.Attribute(XName.Get("class")).Value == "IBProxyObject" ||
                        viewTag.Attribute(XName.Get("class")).Value == "IBUICustomObject")
                    {
                        continue;
                    }
                    ViewHandler.AddControlToTree(canvasChildrenMember, viewTag);
                }
            }

            // Scale to make it the right dimensions
            rootDomObject.MemberNodes.Add(
                new XamlDomMember(rootDomObject.Type.GetMember("RenderTransform"),
                                  new XamlDomObject(typeof(ScaleTransform),
                                                    new XamlDomMember("CenterX", (IPHONE_WIDTH / 2).ToString()),
                                                    new XamlDomMember("CenterY", (IPHONE_HEIGHT / 2).ToString()),
                                                    new XamlDomMember("ScaleX", WIDTHMULTIPLIER.ToString()),
                                                    new XamlDomMember("ScaleY", HEIGHTMULTIPLIER.ToString()))));

            WireNamesAndEvents(rootDomObject, xDocument);

            return(rootDomObject);
        }
Пример #2
0
        private XamlDomObject CreateXamlDom(string file)
        {
            var schemaContext = new XamlSchemaContext();

            _document = XDocument.Load(file);
            if (_document?.Root == null)
            {
                throw new NotSupportedException("Failed to find valid XAML document: file");
            }

            var rootDomObject = new XamlDomObject(schemaContext.GetXamlType(typeof(Page)));

            rootDomObject.MemberNodes.Insert(0, new XamlDomMember(XamlLanguage.Class, $"IslandwoodAutoGenNamespace.{Path.GetFileNameWithoutExtension(file)}"));

            var canvas = new XamlDomObject(schemaContext.GetXamlType(typeof(Canvas)));

            rootDomObject.MemberNodes.Add(new XamlDomMember(schemaContext.GetXamlType(typeof(Page)).ContentProperty, canvas));

            var canvasChildrenMember = new XamlDomMember(schemaContext.GetXamlType(typeof(Canvas)).ContentProperty);

            canvas.MemberNodes.Add(canvasChildrenMember);

            // TODO: This may no longer be needed but it's referenced in certain control handlers so more investigation required

            /*
             * rootDomObject.MemberNodes.Add(
             *  new XamlDomMember(rootDomObject.Type.GetMember("RenderTransform"),
             *      new XamlDomObject(typeof(ScaleTransform),
             *          new XamlDomMember("CenterX", (IPHONE_WIDTH/2).ToString()),
             *          new XamlDomMember("CenterY", (IPHONE_HEIGHT/2).ToString()),
             *          new XamlDomMember("ScaleX", WidthMultiplier.ToString(CultureInfo.InvariantCulture)),
             *          new XamlDomMember("ScaleY", HeightMultiplier.ToString(CultureInfo.InvariantCulture)))));
             */

            var rootObjectsTag = _document.Root.Element(XName.Get("objects"));

            if (rootObjectsTag == null)
            {
                throw new NotSupportedException("Failed to find XML node: objects");
            }

            var placeholderTag = GetElementWithMatchingAttribute(rootObjectsTag, "placeholderIdentifier", "IBFilesOwner");

            if (placeholderTag == null)
            {
                throw new NotSupportedException("Failed to find XML node with required attribute: placeholderIdentifier");
            }

            // Loop over outlets vwhere property attribute is a view
            foreach (var outletElement in
                     from outletNode in placeholderTag.Descendants(XName.Get("outlet"))
                     let propertyAttr = outletNode.Attribute(XName.Get("property"))
                                        where propertyAttr != null && propertyAttr.Value == "view"
                                        select outletNode)
            {
                // Find the node with the matching ID
                var destinationAttr = outletElement.Attribute(XName.Get("destination"));
                if (destinationAttr == null)
                {
                    throw new NotSupportedException("Failed to find XML outlet node with required attribute: destination");
                }

                // TODO: Handle the possibility that subviews don't exist
                var viewTag     = GetElementWithMatchingAttribute(rootObjectsTag, "id", destinationAttr.Value);
                var subviewsTag = viewTag.Element(XName.Get("subviews"));
                if (subviewsTag != null)
                {
                    foreach (var subviewTag in from objectTag in subviewsTag.Elements()
                             let attriNode = objectTag.Attribute(XName.Get("id"))
                                             where attriNode != null
                                             select objectTag)
                    {
                        // Build the tree
                        ViewHandler.AddControlToTree(canvasChildrenMember, subviewTag);
                    }
                }
            }

            // Second pass over the outlets to insert x:Name and x:Bind against added controls
            WireNamesAndEvents(placeholderTag);

            return(rootDomObject);
        }