示例#1
0
        void ProcessAttributesToMember(XamlSchemaContext sctx, StartTagInfo sti, XamlType xt)
        {
            foreach (var p in sti.Attributes)
            {
                int    nsidx   = p.Key.IndexOf(':');
                string prefix  = nsidx > 0 ? p.Key.Substring(0, nsidx) : String.Empty;
                string aname   = nsidx > 0 ? p.Key.Substring(nsidx + 1) : p.Key;
                int    propidx = aname.IndexOf('.');
                if (propidx > 0)
                {
                    string apns   = r.LookupNamespace(prefix);
                    var    apname = aname.Substring(0, propidx);
                    var    axtn   = new XamlTypeName(apns, apname, null);

                    if (xt.UnderlyingType == null)
                    {
                        var am = XamlMember.FromUnknown(aname.Substring(propidx + 1), apns, new XamlType(apns, apname, new List <XamlType>(), sctx));
                        sti.Members.Add(new Pair(am, p.Value));
                    }
                    else
                    {
                        var at = sctx.GetXamlType(axtn);
                        var am = at.GetAttachableMember(aname.Substring(propidx + 1));
                        if (am != null)
                        {
                            sti.Members.Add(new Pair(am, p.Value));
                        }
                        else
                        {
                            sti.Members.Add(new Pair(XamlMember.FromUnknown(aname, apns, new XamlType(apns, apname, new List <XamlType>(), sctx)), p.Value));
                        }
                    }
                }
                else
                {
                    var xm = xt.GetMember(aname);
                    if (xm != null)
                    {
                        sti.Members.Add(new Pair(xm, p.Value));
                    }
                    else
                    {
                        sti.Members.Add(new Pair(XamlMember.FromUnknown(p.Key, r.NamespaceURI, xt), p.Value));
                    }
                }
            }
        }
示例#2
0
        // member element, implicit member, children via content property, or value
        IEnumerable <XamlXmlNodeInfo> ReadMemberElement(XamlType parentType, XamlType xt)
        {
            if (IsIgnored(r.Prefix))
            {
                r.Skip();
                yield break;
            }

            XamlMember xm   = null;
            var        name = r.LocalName;
            int        idx  = name.IndexOf('.');

            // FIXME: it skips strict type name check, as it could result in MarkupExtension mismatch (could be still checked, though)
            if (idx >= 0 /* && name.Substring (0, idx) == xt.Name*/)
            {
                name = name.Substring(idx + 1);
                xm   = xt.GetMember(name);
            }
            else
            {
                xm = (XamlMember)FindStandardDirective(name, AllowedMemberLocations.MemberElement) ??
                     // not a standard directive? then try attachable
                     xt.GetAttachableMember(name) ??
                     // still not? then try ordinal member
                     xt.GetMember(name);
                if (xm == null)
                {
                    // still not? could it be omitted as content property or items ?
                    if ((xm = GetExtraMember(xt)) != null)
                    {
                        // Note that this does not involve r.Read()
                        foreach (var ni in ReadMember(xt, xm))
                        {
                            yield return(ni);
                        }
                        yield break;
                    }
                }
            }
            if (xm == null)
            {
                // Current element could be for another member in the parent type (if exists)
                if (parentType != null && parentType.GetMember(name) != null)
                {
                    // stop the iteration and signal the caller to not read current element as an object. (It resolves conflicts between "start object for current collection's item" and "start member for the next member in the parent object".
                    yield return(Node(XamlNodeType.None, null));

                    yield break;
                }

                // ok, then create unknown member.
                if (idx >= 0)
                {
                    var declaringType = new XamlType(r.NamespaceURI, r.LocalName.Substring(0, idx), new List <XamlType>(), new XamlSchemaContext());

                    xm = XamlMember.FromUnknown(name, r.NamespaceURI, declaringType);                     // FIXME: not sure if isAttachable is always false.
                }
                else
                {
                    xm = XamlMember.FromUnknown(name, r.NamespaceURI, xt);                     // FIXME: not sure if isAttachable is always false.
                }
            }

            if (!r.IsEmptyElement)
            {
                if (idx == -1 && !xm.IsDirective && xm.DeclaringType.UnderlyingType == null)
                {
                    foreach (var ni in ReadCollectionItems(xt, xm))
                    {
                        yield return(ni);
                    }
                }
                else
                {
                    r.Read();
                    foreach (var ni in ReadMember(xt, xm))
                    {
                        yield return(ni);
                    }

                    if (!r.IsEmptyElement)
                    {
                        r.MoveToContent();
                        r.ReadEndElement();
                    }
                }
            }
            else
            {
                if (r.Name.Contains(".") && r.IsEmptyElement && !r.HasAttributes)
                {
                    // This case is present to handle self closing attached property nodes.

                    yield return(Node(XamlNodeType.StartMember, xm));

                    yield return(Node(XamlNodeType.EndMember, xm));

                    r.Read();
                    yield break;
                }
                else
                {
                    foreach (var ni in ReadCollectionItems(xt, xm))
                    {
                        yield return(ni);
                    }
                }
            }
        }