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");
3: foreach (XamlDomObject domObject in rootObject.DescendantsAndSelf())
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:
2: foreach (XamlDomObject objectNode in
3: from control in rootObject.DescendantsAndSelf(typeof(Control))
4: where !control.HasMember("Background")
5: select control)
7: objectNode.SetMemberValue("Background", "Red");
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.
XamlDom is very nice. I really would like to use it for my Editor/Designer.
The problem is that I have to preserve the original file formatting in the XamlDom-edited- and saved file. Is this possible? If not, could I use the StartLineNumber,EndLineNumber, StartLinePosition, EndLinePosition to edit the orginal file as string? I made a short test but XamlDomMember gives me the identical positions for Start/EndlineNumber and Start/EndlinePosition. XamlDomObject seems to give the right positions. I think giving the XamlDom a Save Method is the only correct way. Maybe there is another way to prevent my file formatting??
@mateook -- Cider and Blend have their own XAML DOMs that preserve the source xaml, however, the XAML DOM provided in the XAML Toolkit does not provide this capability. It is possible with some extra work.
The basic approach you could take is:
1) Keep a text buffer of the xaml source file contents
2) As you make modifications in the DOM, track changes
3) Before saving the text buffer, apply the changes to the text buffer
@JenniferLee- OK, like I wrote, using a text buffer is my second choice. In that case I would like to use the XamlDom and track the changes in my text using XamlDomMember Start/Endline, Start/EndPos. Is it a bug that Start/Endpos have identical values? Is it a good Idea to use those positions?