Microsoft XAML Toolkit CTP – July 2010: XAML DOM

This post describes the XAML DOM feature of the XAML Toolkit CTP – July 2010, announced here and downloadable here.  It borrows heavily from Mike Shim’s post announcing the first CTP.

Here’s a simple example of reading a XAML document and writing out all the types used:

    1: XamlDomObject rootObject = XamlDomServices.Load("Window1.xaml");
    2:  
    3: foreach (XamlDomObject domObject in rootObject.DescendantsAndSelf())
    4: {
    5:   Console.WriteLine(domObject.Type);
    6: }

By calling XamlDomServices.Load, we get a XamlDomObject for the root object in the XAML document.  From there, we can call DescendantsAndSelf (similar to XML XElement) on the root object which returns an IEnumerable<XamlDomObject>.

Here’s another example.  Imagine you want to set Background on every Control in your document that doesn’t already have one:

    1: XamlDomObject rootObject = XamlDomServices.Load("Window1.xaml");
    2: foreach (XamlDomObject objectNode in
    3:         from control in rootObject.DescendantsAndSelf(typeof(Control))
    4:         where !control.HasMember("Background")
    5:         select control)
    6: {
    7:   objectNode.SetMemberValue("Background", "Red");
    8: }
    9: XamlDomServices.Save(rootObject, "NewFile.xaml");

The call to DescendantsAndSelf this time is passed typeof(Control).  This will limit it to return only things that are assignable to Control.  We are leveraging LINQ to easily restrict the returned XamlDomObjects to only the ones without a “Background” member.  We then set the background property to Red with SetMemberValue("Background", "Red").  Finally, we call XamlDomServices.Save to save the file back out to XAML.  This is a pretty simple example of a transformation but we can do much more complex transformations with our XamlDom.