XAML 2009 Features: Node Loop flexibility


 


[This is part of a series on New WPF\XAML Features] 


 


So by now most of you must have noticed the System.Xaml dll as part of your .NET 4 WPF projects. It’s a well componentized XAML stack that provides a lot of flexibility working with XAML. So at the core we a System.Xaml.XamlReader and XamlWriter which provide the base implementation and definition for a reader and writer. XamlXmlReader is a reader that reads in XAML and produces a XAML node stream. This stream is then consumed by a XamlXmlWriter XamlObjectWriter to produce the object graph. Similarly for the Save path, you have the XamlObjectReader and XamlXmlWriter.


 


So the Load Path looks like


XAML  à XXR à Node Stream à XOW à Object Graph


 


The Save path would look like


Object Graph à XOR à Node Stream à XXW à XAML


 


Prior to .NET 4, you didn’t have access to the internals; the access points were XamlReader.Load and XamlWriter.Save in PresentationFramework. In .NET 4, we provide access to the node stream and you could manipulate this node loop. There are 7 XamlNodeType’s that you need to look out for in this node loop.


 


An example of a node loop could be filtering out events and unknown elements. Wouldn’t that make a nice feature in XamlPadX J..


 


The code below shows how we could replace the Window in the Xaml passed with a Page.


 


XmlReader xmlReader = XmlReader.Create(input);


XamlXmlReader reader = new XamlXmlReader(xmlReader, System.Windows.Markup.XamlReader.GetWpfSchemaContext());


XamlObjectWriter writer = new XamlObjectWriter(reader.SchemaContext);


 


while (reader.Read())


{


    switch (reader.NodeType)


    {


        case XamlNodeType.StartObject:


            if (!reader.Type.Name.Equals(“Window”))


                writer.WriteNode(reader);


            else


                writer.WriteStartObject(new XamlType(typeof(Page), reader.SchemaContext));


            break;


 


        case XamlNodeType.EndObject:


        case XamlNodeType.StartMember:


        case XamlNodeType.EndMember:


        case XamlNodeType.Value:


        case XamlNodeType.GetObject:


        case XamlNodeType.NamespaceDeclaration:


            writer.WriteNode(reader);


            break;


    }


}


 


Attached is a project that shows how events\unknown elements could be filtered.



Share this post

 

NodeLoop.zip

Comments (2)

  1. Mike Goatly says:

    Nice – it’s alway handy to have the option to hook into this kind of thing.

    One thing though, in the opening paragraph shouldn’t "This stream is then consumed by a XamlXmlWriter to produce the object graph" be referencing XamlObjectWriter?

  2. llester says:

    thats right.. fixed.. 🙂