Browse Source

XamlDom: better support for element collections.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2418 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 19 years ago
parent
commit
0564fc244a
  1. 108
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelCollectionElementsCollection.cs
  2. 41
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/ModelTests.cs
  3. 14
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/CollectionElementsCollection.cs
  4. 2
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/WpfDesign.XamlDom.csproj
  5. 5
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlMarkupValue.cs
  6. 14
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlObject.cs
  7. 16
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlParser.cs
  8. 214
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlProperty.cs
  9. 51
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlPropertyValue.cs
  10. 143
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlTextValue.cs
  11. 2
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.sln

108
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelCollectionElementsCollection.cs

@ -13,31 +13,94 @@ using ICSharpCode.WpfDesign.XamlDom; @@ -13,31 +13,94 @@ using ICSharpCode.WpfDesign.XamlDom;
namespace ICSharpCode.WpfDesign.Designer.Xaml
{
sealed class XamlModelCollectionElementsCollection : Collection<DesignItem>
sealed class XamlModelCollectionElementsCollection : IList<DesignItem>
{
readonly XamlModelProperty modelProperty;
readonly XamlProperty property;
readonly XamlDesignContext context;
public XamlModelCollectionElementsCollection(XamlModelProperty modelProperty, XamlProperty property)
{
this.modelProperty = modelProperty;
this.property = property;
this.context = (XamlDesignContext)modelProperty.DesignItem.Context;
}
XamlDesignContext context = (XamlDesignContext)modelProperty.DesignItem.Context;
foreach (XamlPropertyValue val in property.CollectionElements) {
//context._componentService.GetDesignItem(val);
if (val is XamlObject) {
base.InsertItem(this.Count, context._componentService.GetDesignItem( ((XamlObject)val).Instance ));
public int Count {
get {
return property.CollectionElements.Count;
}
}
public bool IsReadOnly {
get {
return false;
}
}
protected override void ClearItems()
public void Add(DesignItem item)
{
property.CollectionElements.Add(CheckItem(item).XamlObject);
}
public void Clear()
{
base.ClearItems();
property.CollectionElements.Clear();
}
public bool Contains(DesignItem item)
{
XamlDesignItem xitem = CheckItemNoException(item);
if (xitem != null)
return property.CollectionElements.Contains(xitem.XamlObject);
else
return false;
}
public int IndexOf(DesignItem item)
{
XamlDesignItem xitem = CheckItemNoException(item);
if (xitem != null)
return property.CollectionElements.IndexOf(xitem.XamlObject);
else
return -1;
}
public void CopyTo(DesignItem[] array, int arrayIndex)
{
Func.ToArray(this).CopyTo(array, arrayIndex);
}
public bool Remove(DesignItem item)
{
XamlDesignItem xitem = CheckItemNoException(item);
if (xitem != null)
return property.CollectionElements.Remove(xitem.XamlObject);
else
return false;
}
public IEnumerator<DesignItem> GetEnumerator()
{
foreach (XamlPropertyValue val in property.CollectionElements) {
yield return GetItem(val);
}
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
DesignItem GetItem(XamlPropertyValue val)
{
if (val is XamlObject) {
return context._componentService.GetDesignItem( ((XamlObject)val).Instance );
} else {
throw new NotImplementedException();
}
}
XamlDesignItem CheckItem(DesignItem item)
{
if (item == null)
@ -49,29 +112,28 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml @@ -49,29 +112,28 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml
return xitem;
}
protected override void InsertItem(int index, DesignItem item)
XamlDesignItem CheckItemNoException(DesignItem item)
{
XamlDesignItem xitem = CheckItem(item);
property.CollectionElements.Insert(index, xitem.XamlObject);
return item as XamlDesignItem;
}
base.InsertItem(index, item);
public DesignItem this[int index] {
get {
return GetItem(property.CollectionElements[index]);
}
set {
property.CollectionElements[index] = CheckItem(value).XamlObject;
}
}
protected override void RemoveItem(int index)
public void Insert(int index, DesignItem item)
{
XamlDesignItem item = (XamlDesignItem)this[index];
property.CollectionElements.RemoveAt(index);
base.RemoveItem(index);
property.CollectionElements.Insert(index, CheckItem(item).XamlObject);
}
protected override void SetItem(int index, DesignItem item)
public void RemoveAt(int index)
{
XamlDesignItem xitem = CheckItem(item);
property.CollectionElements[index] = xitem.XamlObject;
base.SetItem(index, item);
property.CollectionElements.RemoveAt(index);
}
}
}

41
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/ModelTests.cs

@ -30,6 +30,15 @@ namespace ICSharpCode.WpfDesign.Designer.Tests @@ -30,6 +30,15 @@ namespace ICSharpCode.WpfDesign.Designer.Tests
AssertLog("");
}
[Test]
public void SetButtonWidthElementSyntax()
{
DesignItem button = CreateCanvasContext("<Button><Button.Width>50</Button.Width></Button>");
button.Properties["Width"].SetValue(100.0);
AssertCanvasDesignerOutput("<Button Width=\"100\">\n</Button>", button.Context);
AssertLog("");
}
[Test]
public void UndoRedoTest()
{
@ -80,7 +89,7 @@ namespace ICSharpCode.WpfDesign.Designer.Tests @@ -80,7 +89,7 @@ namespace ICSharpCode.WpfDesign.Designer.Tests
[Test]
public void AddTextBoxToStackPanel()
public void AddTextBoxToCanvas()
{
DesignItem button = CreateCanvasContext("<Button/>");
DesignItem canvas = button.Parent;
@ -89,5 +98,35 @@ namespace ICSharpCode.WpfDesign.Designer.Tests @@ -89,5 +98,35 @@ namespace ICSharpCode.WpfDesign.Designer.Tests
AssertCanvasDesignerOutput("<Button />\n<TextBox />", button.Context);
AssertLog("");
}
[Test]
public void AddTextBoxToCanvasExplicitChildrenCollection()
{
DesignItem button = CreateCanvasContext("<Canvas.Children><Button/></Canvas.Children>");
DesignItem canvas = button.Parent;
DesignItem textBox = canvas.Services.Component.RegisterComponentForDesigner(new TextBox());
canvas.Properties["Children"].CollectionElements.Add(textBox);
AssertCanvasDesignerOutput("<Canvas.Children>\n <Button />\n <TextBox />\n</Canvas.Children>", button.Context);
AssertLog("");
}
[Test]
public void InsertTextBoxInCanvas()
{
DesignItem button = CreateCanvasContext("<Canvas.Width>50</Canvas.Width><Button/><Canvas.Height>60</Canvas.Height>");
DesignItem canvas = button.Parent;
DesignItem textBox = canvas.Services.Component.RegisterComponentForDesigner(new TextBox());
canvas.Properties["Children"].CollectionElements.Add(textBox);
DesignItem checkBox = canvas.Services.Component.RegisterComponentForDesigner(new CheckBox());
canvas.Properties["Children"].CollectionElements.Insert(0, checkBox);
AssertCanvasDesignerOutput("<Canvas.Width>50</Canvas.Width>\n" +
"<CheckBox />\n" +
"<Button />\n" +
"<TextBox />\n" +
"<Canvas.Height>60</Canvas.Height>", button.Context);
AssertLog("");
}
}
}

14
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/CollectionElementsCollection.cs

@ -10,8 +10,6 @@ using System.Collections.ObjectModel; @@ -10,8 +10,6 @@ using System.Collections.ObjectModel;
using System.Collections.Generic;
namespace ICSharpCode.WpfDesign.XamlDom
{
partial class XamlProperty
{
/// <summary>
/// The collection used by XamlProperty.CollectionElements
@ -25,7 +23,10 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -25,7 +23,10 @@ namespace ICSharpCode.WpfDesign.XamlDom
this.property = property;
}
internal void AddByParser(XamlPropertyValue value)
/// <summary>
/// Used by parser to construct the collection without changing the XmlDocument.
/// </summary>
internal void AddInternal(XamlPropertyValue value)
{
base.InsertItem(this.Count, value);
}
@ -56,11 +57,16 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -56,11 +57,16 @@ namespace ICSharpCode.WpfDesign.XamlDom
object collection = info.GetValue(property.ParentObject.Instance);
info.AddValue(collection, item);
item.AddNodeTo(property);
item.ParentProperty = property;
property.InsertNodeInCollection(item.GetNodeForCollection(), index);
base.InsertItem(index, item);
}
protected override void SetItem(int index, XamlPropertyValue item)
{
RemoveItem(index);
InsertItem(index, item);
}
}
}

2
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/WpfDesign.XamlDom.csproj

@ -68,6 +68,8 @@ @@ -68,6 +68,8 @@
<Compile Include="XamlParserSettings.cs" />
<Compile Include="XamlProperty.cs" />
<Compile Include="XamlPropertyInfo.cs" />
<Compile Include="XamlPropertyValue.cs" />
<Compile Include="XamlTextValue.cs" />
<Compile Include="XamlTypeFinder.cs" />
</ItemGroup>
</Project>

5
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlMarkupValue.cs

@ -44,5 +44,10 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -44,5 +44,10 @@ namespace ICSharpCode.WpfDesign.XamlDom
{
markupObject.AddNodeTo(property);
}
internal override System.Xml.XmlNode GetNodeForCollection()
{
return markupObject.GetNodeForCollection();
}
}
}

14
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlObject.cs

@ -8,6 +8,7 @@ @@ -8,6 +8,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Xml;
namespace ICSharpCode.WpfDesign.XamlDom
@ -35,6 +36,14 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -35,6 +36,14 @@ namespace ICSharpCode.WpfDesign.XamlDom
/// <summary>For use by XamlParser only.</summary>
internal void AddProperty(XamlProperty property)
{
#if DEBUG
if (property.IsAttached == false) {
foreach (XamlProperty p in properties) {
if (p.IsAttached == false && p.PropertyName == property.PropertyName)
Debug.Fail("duplicate property");
}
}
#endif
properties.Add(property);
}
@ -43,6 +52,11 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -43,6 +52,11 @@ namespace ICSharpCode.WpfDesign.XamlDom
{
return instance;
}
internal override XmlNode GetNodeForCollection()
{
return element;
}
#endregion
internal XmlElement XmlElement {

16
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlParser.cs

@ -208,7 +208,7 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -208,7 +208,7 @@ namespace ICSharpCode.WpfDesign.XamlDom
if (childValue != null) {
if (defaultProperty != null && defaultProperty.IsCollection) {
defaultProperty.AddValue(defaultPropertyValue, childValue);
defaultCollectionProperty.ParserAddCollectionElement(childValue);
defaultCollectionProperty.ParserAddCollectionElement(null, childValue);
} else {
if (setDefaultValueTo != null)
throw new XamlLoadException("default property may have only one value assigned");
@ -360,11 +360,19 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -360,11 +360,19 @@ namespace ICSharpCode.WpfDesign.XamlDom
if (propertyInfo.IsCollection) {
if (defaultProperty.FullyQualifiedName == propertyInfo.FullyQualifiedName) {
collectionInstance = defaultPropertyValue;
foreach (XamlProperty existing in obj.Properties) {
if (existing.propertyInfo == defaultProperty) {
collectionProperty = existing;
break;
}
}
} else {
collectionInstance = propertyInfo.GetValue(obj.Instance);
}
if (collectionProperty == null) {
obj.AddProperty(collectionProperty = new XamlProperty(obj, propertyInfo, null));
}
}
XmlSpace oldXmlSpace = currentXmlSpace;
if (element.HasAttribute("xml:space")) {
@ -376,13 +384,15 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -376,13 +384,15 @@ namespace ICSharpCode.WpfDesign.XamlDom
if (childValue != null) {
if (propertyInfo.IsCollection) {
propertyInfo.AddValue(collectionInstance, childValue);
collectionProperty.ParserAddCollectionElement(childValue);
collectionProperty.ParserAddCollectionElement(element, childValue);
} else {
if (valueWasSet)
throw new XamlLoadException("non-collection property may have only one child element");
valueWasSet = true;
propertyInfo.SetValue(obj.Instance, childValue.GetValueFor(propertyInfo));
obj.AddProperty(new XamlProperty(obj, propertyInfo, childValue));
XamlProperty xp = new XamlProperty(obj, propertyInfo, childValue);
xp.ParserSetPropertyElement(element);
obj.AddProperty(xp);
}
}
}

214
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlProperty.cs

@ -17,10 +17,10 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -17,10 +17,10 @@ namespace ICSharpCode.WpfDesign.XamlDom
/// <summary>
/// Describes a property on a <see cref="XamlObject"/>.
/// </summary>
public sealed partial class XamlProperty
public sealed class XamlProperty
{
XamlObject parentObject;
XamlPropertyInfo propertyInfo;
internal readonly XamlPropertyInfo propertyInfo;
XamlPropertyValue propertyValue;
CollectionElementsCollection collectionElements;
@ -133,11 +133,28 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -133,11 +133,28 @@ namespace ICSharpCode.WpfDesign.XamlDom
internal void ParserSetPropertyElement(XmlElement propertyElement)
{
XmlElement oldPropertyElement = _propertyElement;
if (oldPropertyElement == propertyElement) return;
_propertyElement = propertyElement;
if (oldPropertyElement != null && IsCollection) {
Debug.WriteLine("Property element for " + this.PropertyName + " already exists, merging..");
foreach (XamlPropertyValue val in this.collectionElements) {
val.RemoveNodeFromParent();
val.AddNodeTo(this);
}
oldPropertyElement.ParentNode.RemoveChild(oldPropertyElement);
}
}
internal void AddChildNodeToProperty(XmlNode newChildNode)
{
if (this.IsCollection) {
// this is the default collection
InsertNodeInCollection(newChildNode, collectionElements.Count);
return;
}
if (_propertyElement == null) {
_propertyElement = parentObject.OwnerDocument.XmlDocument.CreateElement(
this.PropertyTargetType.Name + "." + this.PropertyName,
@ -148,6 +165,36 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -148,6 +165,36 @@ namespace ICSharpCode.WpfDesign.XamlDom
_propertyElement.AppendChild(newChildNode);
}
internal void InsertNodeInCollection(XmlNode newChildNode, int index)
{
Debug.Assert(index >= 0 && index <= collectionElements.Count);
XmlElement collection = _propertyElement;
if (collection == null) {
if (collectionElements.Count == 0) {
// we have to create the collection element
_propertyElement = parentObject.OwnerDocument.XmlDocument.CreateElement(
this.PropertyTargetType.Name + "." + this.PropertyName,
parentObject.OwnerDocument.GetNamespaceFor(this.PropertyTargetType)
);
parentObject.XmlElement.AppendChild(_propertyElement);
collection = _propertyElement;
} else {
// this is the default collection
collection = parentObject.XmlElement;
}
}
if (collectionElements.Count == 0) {
// collection is empty -> we may insert anywhere
collection.AppendChild(newChildNode);
} else if (index == collectionElements.Count) {
// insert after last element in collection
collection.InsertAfter(newChildNode, collectionElements[collectionElements.Count - 1].GetNodeForCollection());
} else {
// insert before specified index
collection.InsertBefore(newChildNode, collectionElements[index].GetNodeForCollection());
}
}
/// <summary>
/// Gets if the property is a collection property.
/// </summary>
@ -215,10 +262,17 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -215,10 +262,17 @@ namespace ICSharpCode.WpfDesign.XamlDom
/// used internally by the XamlParser.
/// Add a collection element that already is part of the XML DOM.
/// </summary>
internal void ParserAddCollectionElement(XamlPropertyValue val)
internal void ParserAddCollectionElement(XmlElement collectionPropertyElement, XamlPropertyValue val)
{
collectionElements.AddByParser(val);
if (collectionPropertyElement != null && _propertyElement == null) {
ParserSetPropertyElement(collectionPropertyElement);
}
collectionElements.AddInternal(val);
val.ParentProperty = this;
if (collectionPropertyElement != _propertyElement) {
val.RemoveNodeFromParent();
val.AddNodeTo(this);
}
}
/// <summary>
@ -251,156 +305,4 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -251,156 +305,4 @@ namespace ICSharpCode.WpfDesign.XamlDom
}
}*/
}
/// <summary>
/// Used for the value of a <see cref="XamlProperty"/>.
/// Can be a <see cref="XamlTextValue"/> or a <see cref="XamlObject"/>.
/// </summary>
public abstract class XamlPropertyValue
{
/// <summary>
/// used internally by the XamlParser.
/// </summary>
internal abstract object GetValueFor(XamlPropertyInfo targetProperty);
XamlProperty _parentProperty;
/// <summary>
/// Gets the parent property that this value is assigned to.
/// </summary>
public XamlProperty ParentProperty {
get { return _parentProperty; }
internal set {
_parentProperty = value;
OnParentPropertyChanged();
}
}
internal virtual void OnParentPropertyChanged()
{
}
internal abstract void RemoveNodeFromParent();
internal abstract void AddNodeTo(XamlProperty property);
}
/// <summary>
/// A textual value in a .xaml file.
/// </summary>
public sealed class XamlTextValue : XamlPropertyValue
{
XmlAttribute attribute;
XmlText textNode;
XmlSpace xmlSpace;
string textValue;
internal XamlTextValue(XmlAttribute attribute)
{
this.attribute = attribute;
}
internal XamlTextValue(string textValue)
{
this.textValue = textValue;
}
internal XamlTextValue(XmlText textNode, XmlSpace xmlSpace)
{
this.xmlSpace = xmlSpace;
this.textNode = textNode;
}
/// <summary>
/// The text represented by the value.
/// </summary>
public string Text {
get {
if (attribute != null)
return attribute.Value;
else if (textValue != null)
return textValue;
else
return NormalizeWhitespace(textNode.Value);
}
set {
if (value == null)
throw new ArgumentNullException("value");
if (attribute != null)
attribute.Value = value;
else if (textValue != null)
textValue = value;
else
textNode.Value = value;
}
}
string NormalizeWhitespace(string text)
{
if (xmlSpace == XmlSpace.Preserve) {
return text.Replace("\r", "");
}
StringBuilder b = new StringBuilder();
bool wasWhitespace = true;
foreach (char c in text) {
if (char.IsWhiteSpace(c)) {
if (!wasWhitespace) {
b.Append(' ');
}
wasWhitespace = true;
} else {
wasWhitespace = false;
b.Append(c);
}
}
if (b.Length > 0 && wasWhitespace)
b.Length -= 1;
return b.ToString();
}
internal override object GetValueFor(XamlPropertyInfo targetProperty)
{
if (targetProperty == null)
return this.Text;
TypeConverter converter = targetProperty.TypeConverter;
if (converter != null) {
return converter.ConvertFromInvariantString(this.Text);
} else {
return this.Text;
}
}
internal override void RemoveNodeFromParent()
{
if (attribute != null)
attribute.OwnerElement.RemoveAttribute(attribute.Name);
else if (textNode != null)
textNode.ParentNode.RemoveChild(textNode);
}
internal override void AddNodeTo(XamlProperty property)
{
if (attribute != null) {
property.ParentObject.XmlElement.Attributes.Append(attribute);
} else if (textValue != null) {
string ns = property.ParentObject.OwnerDocument.GetNamespaceFor(property.PropertyTargetType);
string name;
if (property.IsAttached)
name = property.PropertyTargetType.Name + "." + property.PropertyName;
else
name = property.PropertyName;
if (property.ParentObject.XmlElement.GetPrefixOfNamespace(ns) == "") {
property.ParentObject.XmlElement.SetAttribute(name, textValue);
attribute = property.ParentObject.XmlElement.GetAttributeNode(name);
} else {
property.ParentObject.XmlElement.SetAttribute(name, ns, textValue);
attribute = property.ParentObject.XmlElement.GetAttributeNode(name, ns);
}
textValue = null;
} else {
property.AddChildNodeToProperty(textNode);
}
}
}
}

51
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlPropertyValue.cs

@ -0,0 +1,51 @@ @@ -0,0 +1,51 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Text;
using System.Xml;
namespace ICSharpCode.WpfDesign.XamlDom
{
/// <summary>
/// Used for the value of a <see cref="XamlProperty"/>.
/// Can be a <see cref="XamlTextValue"/> or a <see cref="XamlObject"/>.
/// </summary>
public abstract class XamlPropertyValue
{
/// <summary>
/// used internally by the XamlParser.
/// </summary>
internal abstract object GetValueFor(XamlPropertyInfo targetProperty);
XamlProperty _parentProperty;
/// <summary>
/// Gets the parent property that this value is assigned to.
/// </summary>
public XamlProperty ParentProperty {
get { return _parentProperty; }
internal set {
_parentProperty = value;
OnParentPropertyChanged();
}
}
internal virtual void OnParentPropertyChanged()
{
}
internal abstract void RemoveNodeFromParent();
internal abstract void AddNodeTo(XamlProperty property);
internal abstract XmlNode GetNodeForCollection();
}
}

143
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlTextValue.cs

@ -0,0 +1,143 @@ @@ -0,0 +1,143 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Text;
using System.Xml;
namespace ICSharpCode.WpfDesign.XamlDom
{
/// <summary>
/// A textual value in a .xaml file.
/// </summary>
public sealed class XamlTextValue : XamlPropertyValue
{
XmlAttribute attribute;
XmlText textNode;
XmlSpace xmlSpace;
string textValue;
internal XamlTextValue(XmlAttribute attribute)
{
this.attribute = attribute;
}
internal XamlTextValue(string textValue)
{
this.textValue = textValue;
}
internal XamlTextValue(XmlText textNode, XmlSpace xmlSpace)
{
this.xmlSpace = xmlSpace;
this.textNode = textNode;
}
/// <summary>
/// The text represented by the value.
/// </summary>
public string Text {
get {
if (attribute != null)
return attribute.Value;
else if (textValue != null)
return textValue;
else
return NormalizeWhitespace(textNode.Value);
}
set {
if (value == null)
throw new ArgumentNullException("value");
if (attribute != null)
attribute.Value = value;
else if (textValue != null)
textValue = value;
else
textNode.Value = value;
}
}
string NormalizeWhitespace(string text)
{
if (xmlSpace == XmlSpace.Preserve) {
return text.Replace("\r", "");
}
StringBuilder b = new StringBuilder();
bool wasWhitespace = true;
foreach (char c in text) {
if (char.IsWhiteSpace(c)) {
if (!wasWhitespace) {
b.Append(' ');
}
wasWhitespace = true;
} else {
wasWhitespace = false;
b.Append(c);
}
}
if (b.Length > 0 && wasWhitespace)
b.Length -= 1;
return b.ToString();
}
internal override object GetValueFor(XamlPropertyInfo targetProperty)
{
if (targetProperty == null)
return this.Text;
TypeConverter converter = targetProperty.TypeConverter;
if (converter != null) {
return converter.ConvertFromInvariantString(this.Text);
} else {
return this.Text;
}
}
internal override void RemoveNodeFromParent()
{
if (attribute != null)
attribute.OwnerElement.RemoveAttribute(attribute.Name);
else if (textNode != null)
textNode.ParentNode.RemoveChild(textNode);
}
internal override void AddNodeTo(XamlProperty property)
{
if (attribute != null) {
property.ParentObject.XmlElement.Attributes.Append(attribute);
} else if (textValue != null) {
string ns = property.ParentObject.OwnerDocument.GetNamespaceFor(property.PropertyTargetType);
string name;
if (property.IsAttached)
name = property.PropertyTargetType.Name + "." + property.PropertyName;
else
name = property.PropertyName;
if (property.ParentObject.XmlElement.GetPrefixOfNamespace(ns) == "") {
property.ParentObject.XmlElement.SetAttribute(name, textValue);
attribute = property.ParentObject.XmlElement.GetAttributeNode(name);
} else {
property.ParentObject.XmlElement.SetAttribute(name, ns, textValue);
attribute = property.ParentObject.XmlElement.GetAttributeNode(name, ns);
}
textValue = null;
} else {
property.AddChildNodeToProperty(textNode);
}
}
internal override XmlNode GetNodeForCollection()
{
if (textNode != null)
return textNode;
else
throw new NotImplementedException();
}
}
}

2
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.sln

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
# SharpDevelop 2.1.0.2192
# SharpDevelop 2.1.0.2382
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfDesign.XamlDom", "WpfDesign.XamlDom\Project\WpfDesign.XamlDom.csproj", "{88DA149F-21B2-48AB-82C4-28FB6BDFD783}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfDesign.XamlDom.Tests", "WpfDesign.XamlDom\Tests\WpfDesign.XamlDom.Tests.csproj", "{BD62F5BC-115F-4339-8B5B-96C7A21DC67E}"

Loading…
Cancel
Save