Welcome to WindowsClient.net | Sign in | Join

Rob Relyea - XAMLified

WPF, Silverlight and XAML

Syndication

Sponsors





  • advertise here
XamlNodeLoop Sample – changing Name to x:Name during Save

 

A customer asked if it was possible, for their own XAML Vocabulary, to not write down XAML with Name="foo".  Instead they wanted to write down x:Name="foo".

Here is an example of a way to use a XAML node loop (using a XamlReader and XamlWriter together and doing custom things between the reader and writer) to do that.

using System;
using System.Collections.Generic;
using System.IO;
using System.Xaml;
 
namespace SaveXamlNodeLoopSample
{
    class Program
    {
        static void Main(string[] args)
        {
            string xamlString = "<SampleTag xmlns='clr-namespace:SaveXamlNodeLoopSample;assembly=SaveXamlNodeLoopSample' Name='someName'/>";
 
            object o = XamlServices.Parse(xamlString);
 
            XamlObjectReader xor = new XamlObjectReader(o);
            StringWriter sw = new StringWriter();
            XamlXmlWriter xxw = new XamlXmlWriter(sw, xor.SchemaContext);
 
            SaveUsingXamlName(xor, xxw);
 
            Console.WriteLine(sw.ToString());
        }
 
        private static void SaveUsingXamlName(XamlObjectReader xor, XamlXmlWriter xxw)
        {
            xxw.WriteNamespace(new NamespaceDeclaration(XamlLanguage.Xaml2006Namespace, "x"));
            Stack<XamlType> xamlTypeStack = new Stack<XamlType>();
            while (xor.Read())
            {
                bool swapMember = false;
                switch (xor.NodeType)
                {
                    case XamlNodeType.StartObject:
                        xamlTypeStack.Push(xor.Type);
                        break;
                    case XamlNodeType.GetObject:
                        xamlTypeStack.Push(null); // don't need to get the real type.
                        break;
                    case XamlNodeType.EndObject:
                        xamlTypeStack.Pop();
                        break;
                    case XamlNodeType.StartMember:
                        if (xamlTypeStack.Peek().GetAliasedProperty(XamlLanguage.Name) == xor.Member)
                        {
                            swapMember = true;
                        }
                        break;
                }
 
                if (!swapMember)
                    xxw.WriteNode(xor);
                else
                    xxw.WriteStartMember(XamlLanguage.Name);
            }
        }
    }
 
    [System.Windows.Markup.RuntimeNameProperty("Name")]
    public class SampleTag 
    {
        public string Name { get; set; }
    }
}
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

 

If you have better ways to do this with .NET 4, or any feedback, please comment.

Published Thursday, January 21, 2010 6:08 PM by Rob_Relyea
Filed under:

Comments

# re: XamlNodeLoop Sample – changing Name to x:Name during Save@ Friday, January 22, 2010 7:15 AM

Very timely, I was just reading Adam Nathan's coverage of RuntimeNameProperty. Generally speaking, when a object *does* supply a decorated Name property which form is preferred? The "x:Name" or just "Name"?

by Tom Kirby-Green

# re: XamlNodeLoop Sample – changing Name to x:Name during Save@ Friday, January 22, 2010 8:47 AM

@Tom-

XAML doesn't care. When you load, you can only specify one or the other on each element, or we'll error.

When we save an object graph with XamlServices.Save(), we prefer the property native to the object. Some people, including the customer I was emailing with, wanted x:Name to be written out instead.

I think XamlWriter.Save() prefers the same.

Would love to hear what you think, and why.

Thanks, Rob

# Dew Drop &#8211; January 22, 2010 | Alvin Ashcraft&#039;s Morning Dew@ Friday, January 22, 2010 9:15 AM

Pingback from  Dew Drop &#8211; January 22, 2010 | Alvin Ashcraft&#039;s Morning Dew

# Enlaces Interesantes WPF/Silverlight 22-01-2010@ Friday, January 22, 2010 10:00 AM

Hola vengo con los enlaces interesantes de hoy pero quisiera resaltar uno y establecer un peque&ntilde;o

# Windows Client Developer Roundup for 1/25/2010@ Monday, January 25, 2010 1:56 AM

This is Windows Client Developer roundup #8. I’m off in Reykjavik Iceland this week, speaking about Silverlight

Leave a Comment

(required) 
(required) 
(optional)
(required) 
Page view counter