1: //This .NET 4 Beta 1 example was inspired by the WPF forum question at:
2: // http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/5c226430-c54d-45b8-a8a2-7e4a79e3692a
3: //
4:
5: /*
6: Console output of this example is:
7: XAML Contents:
8: <Window
9: xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
10: xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
11: xmlns:local="clr-namespace:NodeLoopExample;assembly=NodeLoopExample"
12: >
13: <StackPanel>
14: <Button Name="button1">Ok</Button>
15: <Button x:Name="button2">No, it is not ok!</Button>
16: <Button>
17: <Button.Background>
18: <LinearGradientBrush x:Name="brush">
19: <GradientStop Color="AliceBlue" />
20: <GradientStop Color="Red" Offset="1" />
21: </LinearGradientBrush>
22: </Button.Background>
23: Button with color
24: </Button>
25: </StackPanel>
26: </Window>
27:
28: NamedObjects:
29: Name: button1, Type: Button
30: Name: button2, Type: Button
31: Name: brush, Type: LinearGradientBrush
32: --close the window to close the app--
33: */
34:
35: using System;
36: using System.Collections.Generic;
37: using System.Windows;
38: using System.Xaml;
39: using System.Xml;
40: using System.IO;
41:
42: namespace NodeLoopExample
43: {
44: class Program
45: {
46: [STAThread]
47: static void Main(string[] args)
48: {
49: Console.WriteLine("XAML Contents:");
50: string xamlContents = File.ReadAllText("WindowWithNames.xaml");
51: Console.WriteLine(xamlContents);
52: Console.WriteLine();
53:
54: List<Frame> namedObjects = ShowObjectGraphAndHarvestNames("WindowWithNames.xaml");
55: Console.WriteLine("NamedObjects:");
56: foreach (Frame frame in namedObjects)
57: {
58: Console.WriteLine("Name: {0}, Type: {1}", frame.Name, frame.Type.UnderlyingType.Name);
59: }
60:
61: Console.WriteLine("--close the window to close the app--");
62: Application app = new Application();
63: app.Run();
64: }
65:
66: //Let's loop through all the XAML nodes in this XAML file.
67: //We'll keep track of the tag name (Type), attributes or property elements (Member)
68: // names (Name) and instances (Instance) on a Frame class.
69: //We'll return all Frames with a name from this method.
70: //We also want to show the objectGraph created.
71: private static List<Frame> ShowObjectGraphAndHarvestNames(string fileName)
72: {
73: //we use a stack to keep track of names/instances
74: Stack<Frame> stack = new Stack<Frame>();
75:
76: XmlReader xr = XmlReader.Create(fileName);
77: XamlXmlReader reader = new XamlXmlReader(xr);
78: XamlObjectWriter writer = new XamlObjectWriter(reader.SchemaContext);
79:
80: //List of all frames which had names
81: List<Frame> namedObjects = new List<Frame>();
82:
83: while (reader.Read())
84: {
85: writer.WriteNode(reader);
86:
87: switch (reader.NodeType)
88: {
89: case XamlNodeType.StartObject:
90: Frame newFrame = new Frame();
91: newFrame.Type = reader.Type;
92: stack.Push(newFrame);
93: break;
94: case XamlNodeType.GetObject:
95: Frame newFrameForGet = new Frame();
96: newFrameForGet.Type = stack.Peek().Member.Type;
97: stack.Push(newFrameForGet);
98: break;
99: case XamlNodeType.StartMember:
100: stack.Peek().Member = reader.Member;
101: break;
102: case XamlNodeType.EndMember:
103: stack.Peek().Member = null;
104: break;
105: case XamlNodeType.EndObject:
106: stack.Peek().Instance = writer.Result;
107: if (stack.Peek().Name != null)
108: {
109: namedObjects.Add(stack.Peek());
110: }
111: stack.Pop();
112: break;
113: case XamlNodeType.Value:
114: XamlMemberBase contentProperty = stack.Peek().Type.GetAliasedProperty(XamlLanguage.Name);
115: if (stack.Peek().Member == contentProperty
116: || stack.Peek().Member == XamlLanguage.Name)
117: {
118: stack.Peek().Name = reader.Value as string;
119: }
120: break;
121: }
122: }
123:
124: object rootObject = writer.Result;
125: ShowInWindow(rootObject);
126: return namedObjects;
127: }
128:
129: private static void ShowInWindow(object root)
130: {
131: Window window = root as Window;
132: if (window == null)
133: {
134: window = new Window();
135: window.Content = root;
136: }
137: if (window.Title == "")
138: {
139: window.Title = "NodeLoopExample";
140: }
141: window.Height = 400;
142: window.Width = 300;
143: window.Top = 400;
144: window.Left = 400;
145: window.Show();
146: }
147: }
148: class Frame
149: {
150: public XamlType Type { get; set; }
151: public XamlMemberBase Member { get; set; }
152: public string Name { get; set; }
153: public object Instance { get; set; }
154: }
155: }