Partilhar via


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

  • Anonymous
    November 09, 2009
    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?

  • Anonymous
    November 10, 2009
    thats right.. fixed.. :)