Microsoft XAML Toolkit CTP – July 2010: XAML DOM


The official blog of the Windows Presentation Foundation Team

Microsoft XAML Toolkit CTP – July 2010: XAML DOM

  • Comments 4

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.

Leave a Comment
  • Please add 3 and 1 and type the answer here:
  • Post
  • 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

    Thanks,

    Jennifer

  • @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?

  • EndPosition == StartPosition is a 'bug'.

    The XAML DOM gets it's line number information from the XamlXmlReader.  The XamlXmlReader gets it's line number information from the XML reader which is possibly not the number you want.  For example the EndPosition of a DomObject is the first character of the XML End tag Name.  Why not the last character of the end tag name?   In light of that it makes sense that the End Position of an attribute is same as the start position.

    The XAML DOM API was designed to have Start and End line information because we relize that it is important for a DOM to provide this for editor senarios.  But in this pre-release nothing extra was done to make it nice.  Of course be aware that if we improve this in a future release, the values of the Line/Position numbers will change.

    I doubt that XamlDomServices.Save() will ever write out perfect source that exactly matches the input.  The best "source preserving" solution will continue to be a DOM nodes with references into your own text buffer.

Page 1 of 1 (4 items)