+2005-08-31 Iain McCoy <iain@mccoy.id.au>
+
+ * System.Windows.Serialization/Parser.cs,
+ System.Windows.Serialization/data-classes.txt,
+ Mono.Windows.Serialization/ParserToCode.cs,
+ Mono.Windows.Serialization/ParserConsumerBase.cs
+ Mono.Windows.Serialization/XamlParser.cs: initial support for
+ x:Key and StaticResource - these exist mainly to support the styling
+ system that will eventually live in System.Windows
+
2005-08-28 Iain McCoy <iain@mccoy.id.au>
* Test/Parser.cs, Test/ParserToCode.cs: added tests for objects as
CreateTopLevel(((XamlElementStartNode)n).ElementType, ((XamlElementStartNode)n).name);
} else if (n is XamlElementStartNode && ((XamlElementStartNode)n).propertyObject) {
Debug.WriteLine(this.GetType() + ": element begins as property value");
- CreatePropertyObject(((XamlElementStartNode)n).ElementType, ((XamlElementStartNode)n).name);
+ string key = getKeyFromNode(n);
+ CreatePropertyObject(((XamlElementStartNode)n).ElementType, ((XamlElementStartNode)n).name, key);
} else if (n is XamlElementStartNode && ((XamlElementStartNode)n).depPropertyObject) {
Debug.WriteLine(this.GetType() + ": element begins as dependency property value");
- CreateDependencyPropertyObject(((XamlElementStartNode)n).ElementType, ((XamlElementStartNode)n).name);
+ string key = getKeyFromNode(n);
+ CreateDependencyPropertyObject(((XamlElementStartNode)n).ElementType, ((XamlElementStartNode)n).name, key);
} else if (n is XamlElementStartNode) {
Debug.WriteLine(this.GetType() + ": element begins");
- CreateObject(((XamlElementStartNode)n).ElementType, ((XamlElementStartNode)n).name);
+ string key = getKeyFromNode(n);
+ CreateObject(((XamlElementStartNode)n).ElementType, ((XamlElementStartNode)n).name, key);
} else if (n is XamlPropertyNode && ((XamlPropertyNode)n).PropInfo != null) {
Debug.WriteLine(this.GetType() + ": normal property begins");
CreateProperty(((XamlPropertyNode)n).PropInfo);
CreateObjectText(((XamlTextNode)n).TextContent);
} else if (n is XamlTextNode && ((XamlTextNode)n).mode == XamlParseMode.Property){
Debug.WriteLine(this.GetType() + ": text for property");
- CreatePropertyText(((XamlTextNode)n).TextContent, ((XamlTextNode)n).finalType);
+ if (((XamlTextNode)n).keyText != null)
+ CreatePropertyReference(((XamlTextNode)n).keyText);
+ else
+ CreatePropertyText(((XamlTextNode)n).TextContent, ((XamlTextNode)n).finalType);
EndProperty();
} else if (n is XamlTextNode && ((XamlTextNode)n).mode == XamlParseMode.DependencyProperty){
Debug.WriteLine(this.GetType() + ": text for dependency property");
- CreateDependencyPropertyText(((XamlTextNode)n).TextContent, ((XamlTextNode)n).finalType);
+ if (((XamlTextNode)n).keyText != null)
+ CreateDependencyPropertyReference(((XamlTextNode)n).keyText);
+ else
+ CreateDependencyPropertyText(((XamlTextNode)n).TextContent, ((XamlTextNode)n).finalType);
EndDependencyProperty();
} else if (n is XamlPropertyComplexEndNode) {
Debug.WriteLine(this.GetType() + ": end complex property");
}
+ private string getKeyFromNode(XamlNode n)
+ {
+ // we know that n is a XamlElementStartNode, but don't need that knowledge
+ if (n is XamlKeyElementStartNode)
+ return ((XamlKeyElementStartNode)n).key;
+ else
+ return null;
+ }
+
public abstract void CreateTopLevel(Type parent, string className);
- public abstract void CreateObject(Type type, string varName);
+ public abstract void CreateObject(Type type, string varName, string key);
public abstract void CreateProperty(PropertyInfo property);
public abstract void CreateEvent(EventInfo evt);
public abstract void CreateDependencyProperty(Type attachedTo, string propertyName, Type propertyType);
public abstract void CreateEventDelegate(string functionName, Type eventDelegateType);
public abstract void CreatePropertyDelegate(string functionName, Type propertyType);
public abstract void CreatePropertyText(string text, Type propertyType);
+ public abstract void CreatePropertyReference(string key);
public abstract void CreateDependencyPropertyText(string text, Type propertyType);
- public abstract void CreateDependencyPropertyObject(Type type, string varName);
- public abstract void CreatePropertyObject(Type type, string varName);
+ public abstract void CreateDependencyPropertyObject(Type type, string varName, string key);
+ public abstract void CreateDependencyPropertyReference(string key);
+ public abstract void CreatePropertyObject(Type type, string varName, string key);
public abstract void EndDependencyPropertyObject(Type destType);
public abstract void EndPropertyObject(Type destType);
public abstract void EndObject();
ArrayList objects = new ArrayList();
Hashtable nameClashes = new Hashtable();
int tempIndex = 0;
+
+ Hashtable keys = new Hashtable();
CodeCompileUnit code;
CodeTypeDeclaration type;
// bottom of stack holds CodeVariableReferenceExpression
// pushes a reference to the new current type
- public override void CreateObject(Type type, string varName)
+ public override void CreateObject(Type type, string varName, string key)
{
debug();
bool isDefaultName;
varName += (int)nameClashes[varName];
}
+ if (key != null)
+ keys[key] = varName;
if (isDefaultName) {
CodeVariableDeclarationStatement declaration =
constructor.Statements.Add(assignment);
}
- public override void CreateDependencyPropertyObject(Type type, string varName)
+
+ public override void CreatePropertyReference(string key)
+ {
+ CodeAssignStatement assignment = new CodeAssignStatement(
+ (CodeExpression)peek(),
+ new CodeVariableReferenceExpression(key));
+
+ constructor.Statements.Add(assignment);
+ }
+ public override void CreateDependencyPropertyReference(string key)
+ {
+ CreatePropertyReference(key);
+ }
+
+ public override void CreateDependencyPropertyObject(Type type, string varName, string key)
{
- CreatePropertyObject(type, varName);
+ CreatePropertyObject(type, varName, key);
}
- public override void CreatePropertyObject(Type type, string varName)
+ public override void CreatePropertyObject(Type type, string varName, string key)
{
debug();
bool isDefaultName;
varName += (int)nameClashes[varName];
}
+ if (key != null)
+ keys[key] = varName;
if (isDefaultName) {
CodeVariableDeclarationStatement declaration =
} else {
parseChildObjectElement(parent);
}
-
+
if (isEmpty)
tempStateCount ++;
processObjectAttributes();
if (reader.GetAttribute("Name", XAML_NAMESPACE) != null)
throw new Exception("The XAML Name attribute can not be applied to top level elements\n"+
"Do you mean the Class attribute?");
+ if (reader.GetAttribute("Key", XAML_NAMESPACE) != null)
+ throw new Exception("The XAML Key attribute can not be applied to top level elements.");
begun = true;
createTopLevel(parent.AssemblyQualifiedName, reader.GetAttribute("Class", XAML_NAMESPACE));
}
if (name == null)
name = reader.GetAttribute("Name", reader.NamespaceURI);
+ string key = reader.GetAttribute("Key", XAML_NAMESPACE);
+
Debug.WriteLine("XamlParser: parent is " + parent);
if (currentState().type == CurrentType.Object ||
currentState().type == CurrentType.PropertyObject ||
currentState().type == CurrentType.DependencyPropertyObject) {
abortIfNotAddChild("object");
- addChild(parent, name);
+ addChild(parent, name, key);
} else if (currentState().type == CurrentType.Property) {
- addPropertyChild(parent, name);
+ addPropertyChild(parent, name, key);
} else if (currentState().type == CurrentType.DependencyProperty) {
- addDependencyPropertyChild(parent, name);
+ addDependencyPropertyChild(parent, name, key);
} else {
throw new NotImplementedException(currentState().type.ToString());
}
continue;
if (reader.NamespaceURI == XAML_NAMESPACE)
continue;
- if (reader.LocalName.IndexOf(".") < 0)
+ else if (reader.LocalName.IndexOf(".") < 0)
parseLocalPropertyAttribute();
else
parseDependencyPropertyAttribute();
push(CurrentType.Object, t);
}
- void addChild(Type type, string objectName)
+ XamlElementStartNode getChildStart(Type type, string key)
{
- nodeQueue.Add(new XamlElementStartNode(
- reader.LineNumber,
- reader.LinePosition,
- getDepth(),
- type.Assembly.FullName,
- type.AssemblyQualifiedName,
- type,
- null));
+ if (key == null) {
+ return new XamlElementStartNode(
+ reader.LineNumber,
+ reader.LinePosition,
+ getDepth(),
+ type.Assembly.FullName,
+ type.AssemblyQualifiedName,
+ type,
+ null);
+ } else {
+ XamlKeyElementStartNode n = new XamlKeyElementStartNode(
+ reader.LineNumber,
+ reader.LinePosition,
+ getDepth(),
+ type.Assembly.FullName,
+ type.AssemblyQualifiedName,
+ type,
+ null);
+ n.setkey(key);
+ return n;
+ }
+ }
+
+ void addChild(Type type, string objectName, string key)
+ {
+ nodeQueue.Add(getChildStart(type, key));
((XamlElementStartNode)topNode()).setname(objectName);
// writer.CreateObject(type, objectName);
push(CurrentType.Object, type);
}
- void addPropertyChild(Type type, string objectName)
+ void addPropertyChild(Type type, string objectName, string key)
{
// writer.CreatePropertyObject(type, objectName);
- nodeQueue.Add(new XamlElementStartNode(
- reader.LineNumber,
- reader.LinePosition,
- getDepth(),
- type.Assembly.FullName,
- type.AssemblyQualifiedName,
- type,
- null));
+ nodeQueue.Add(getChildStart(type, key));
((XamlElementStartNode)topNode()).setname(objectName);
((XamlElementStartNode)topNode()).setpropertyObject(true);
push(CurrentType.PropertyObject, type);
}
- void addDependencyPropertyChild(Type type, string objectName)
+ void addDependencyPropertyChild(Type type, string objectName, string key)
{
// writer.CreatePropertyObject(type, objectName);
- nodeQueue.Add(new XamlElementStartNode(
- reader.LineNumber,
- reader.LinePosition,
- getDepth(),
- type.Assembly.FullName,
- type.AssemblyQualifiedName,
- type,
- null));
+ nodeQueue.Add(getChildStart(type, key));
((XamlElementStartNode)topNode()).setname(objectName);
((XamlElementStartNode)topNode()).setdepPropertyObject(true);
((XamlPropertyNode)nodeQueue[nodeQueue.Count - 1]).setPropInfo(prop);
if (!prop.PropertyType.IsSubclassOf(typeof(Delegate))) {
-
- nodeQueue.Add(new XamlTextNode(
- reader.LineNumber,
- reader.LinePosition,
- getDepth(),
- reader.Value));
+ nodeQueue.Add(getPropertyValueNode());
((XamlTextNode)topNode()).setmode(XamlParseMode.Property);
// writer.CreatePropertyText(reader.Value, prop.PropertyType);
return true;
}
+ XamlTextNode getPropertyValueNode()
+ {
+ XamlTextNode n = new XamlTextNode(
+ reader.LineNumber,
+ reader.LinePosition,
+ getDepth(),
+ reader.Value);
+ if (n.TextContent.StartsWith("{StaticResource ")) {
+ n.setkeyText(n.TextContent.Remove(0, "{StaticResource ".Length).TrimEnd('}'));
+ }
+ return n;
+ }
+
+
+
void ensureDependencyObject(Type currentType)
{
if (!currentType.IsSubclassOf(typeof(System.Windows.DependencyObject)))
false));
((XamlPropertyNode)topNode()).setDP(dp);
- nodeQueue.Add(new XamlTextNode(reader.LineNumber, reader.LinePosition, getDepth(), reader.Value));
+ nodeQueue.Add(getPropertyValueNode());
((XamlTextNode)topNode()).setmode(XamlParseMode.DependencyProperty);
((XamlTextNode)topNode()).setfinalType(dp.PropertyType);
public object instance;
ArrayList objects = new ArrayList();
+ Hashtable keys = new Hashtable();
+
public override void CreateTopLevel(Type parent, string className)
{
instance = Activator.CreateInstance(parent);
push(instance);
}
- public override void CreateObject(Type type, string varName)
+ public override void CreateObject(Type type, string varName, string key)
{
Object o = Activator.CreateInstance(type);
((IAddChild)peek()).AddChild(o);
+
+ if (key != null)
+ keys[key] = o;
push(o);
}
storeToProperty(value);
}
- public override void CreatePropertyObject(Type type, string name)
+ public override void CreatePropertyObject(Type type, string name, string key)
{
object value = Activator.CreateInstance(type);
Debug.WriteLine("ObjectWriter CREATING PROPERTY OBJECT of type" + type);
+ if (key != null)
+ keys[key] = value;
push(value);
}
+
+ public override void CreatePropertyReference(string key)
+ {
+ push(keys[key]);
+ }
+ public override void CreateDependencyPropertyReference(string key)
+ {
+ push(keys[key]);
+ }
public override void EndPropertyObject(Type destType)
{
object value = convertPropertyObjectValue(destType, pop());
}
}
- public override void CreateDependencyPropertyObject(Type type, string name)
+ public override void CreateDependencyPropertyObject(Type type, string name, string key)
{
- CreatePropertyObject(type, name);
+ CreatePropertyObject(type, name, key);
}
public override void EndDependencyPropertyObject(Type finalType)
{
XamlConstructorParametersEndNode
XamlConstructorParametersStartNode
XamlConstructorParameterTypeNode: string valueTypeFullName, string valueAssemblyName, Type valueElementType
-XamlDefAttributeKeyTypeNode(XamlAttributeNode): string assemblyName, string valueType
+XamlDefAttributeKeyTypeNode(XamlAttributeNode): string assemblyName, Type valueType
XamlDefAttributeNode(XamlAttributeNode): string name, +string value
XamlDefTagNode(XamlAttributeNode): bool isEmptyElement, System.Xml.XmlReader xmlReader, string defTagName
XamlDocumentEndNode
XamlElementEndNode; bool propertyObject, bool depPropertyObject, Type finalType
XamlEndAttributesNode: bool compact
XamlKeyElementEndNode(XamlElementEndNode)
-XamlKeyElementStartNode(XamlElementStartNode)
+XamlKeyElementStartNode(XamlElementStartNode); string key
XamlLanguageNode: string language
XamlLiteralContentNode: string content
XamlNode(object): XamlNodeType tokenType, int lineNumber, int linePosition, int depth
XamlPropertyNode(XamlPropertyComplexStartNode): string value, string xmlNamespace, BamlAttributeUsage attributeUsage, bool complexAsSimple
XamlPropertyWithTypeNode(XamlPropertyComplexStartNode): String valueTypeFullName, string valueAssemblyFullName, Type valueElementType, string valueSerializerTypeFullName, string valueSerializerTypeAssemblyName, string xmlNamespace
XamlRoutedEventNode(XamlAttributeNode): System.Windows.RoutedEvent routedEvent, string assemblyName, string typeFullName, string routedEventName, +string value
-XamlTextNode: string textContent; XamlParseMode mode, Type finalType
+XamlTextNode: string textContent; XamlParseMode mode, Type finalType, string keyText
XamlUnknownAttributeNode(XamlAttributeNode): string xmlNamespace, string name, +string value
XamlUnknownTagEndNode
XamlUnknownTagStartNode(XamlAttributeNode): string xmlNamespace, +string value